Minor tweaks to make fill and invert support gpixel operations

This commit is contained in:
Antonis Ryakiotakis 2015-04-30 13:52:25 +02:00
parent 04b23af02d
commit 2d491b8415
6 changed files with 30 additions and 30 deletions

View File

@ -58,7 +58,7 @@ void ED_undo_paint_push_end(int type);
void ED_image_undo_restore(struct bContext *C, struct ListBase *lb);
void ED_image_undo_free(struct ListBase *lb);
void ED_imapaint_clear_partial_redraw(void);
void ED_imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h);
void ED_imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h, bool find_old);
void ED_imapaint_bucket_fill(struct bContext *C, float color[3], struct wmOperator *op);
#endif /* __ED_PAINT_H__ */

View File

@ -215,7 +215,7 @@ void *image_undo_find_tile(Image *ima, ImBuf *ibuf, int x_tile, int y_tile, unsi
return NULL;
}
void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile, unsigned short **mask, bool **valid, bool proj)
void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile, unsigned short **mask, bool **valid, bool proj, bool find_prev)
{
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
UndoImageTile *tile;
@ -226,7 +226,7 @@ void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile,
/* check if tile is already pushed */
/* in projective painting we keep accounting of tiles, so if we need one pushed, just push! */
if (!proj) {
if (find_prev) {
data = image_undo_find_tile(ima, ibuf, x_tile, y_tile, mask, true);
if (data)
return data;
@ -445,7 +445,7 @@ void imapaint_region_tiles(ImBuf *ibuf, int x, int y, int w, int h, int *tx, int
*ty = (y >> IMAPAINT_TILE_BITS);
}
void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h, bool find_old)
{
ImBuf *tmpibuf = NULL;
int tilex, tiley, tilew, tileh, tx, ty;
@ -474,7 +474,7 @@ void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int
for (ty = tiley; ty <= tileh; ty++)
for (tx = tilex; tx <= tilew; tx++)
image_undo_push_tile(ima, ibuf, &tmpibuf, tx, ty, NULL, NULL, false);
image_undo_push_tile(ima, ibuf, &tmpibuf, tx, ty, NULL, NULL, false, find_old);
ibuf->userflags |= IB_BITMAPDIRTY;

View File

@ -1049,7 +1049,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
for (a = 0; a < tot; a++) {
ED_imapaint_dirty_region(s->image, s->canvas,
region[a].destx, region[a].desty,
region[a].width, region[a].height);
region[a].width, region[a].height, true);
if (s->do_masking) {
/* masking, find original pixels tiles from undo buffer to composite over */
@ -1329,12 +1329,12 @@ static void paint_2d_fill_add_pixel_float(
const int x_px, const int y_px, ImBuf *ibuf, BLI_Stack *stack, BLI_bitmap *touched,
const float color[4], float threshold_sq)
{
int coordinate;
size_t coordinate;
if (x_px >= ibuf->x || x_px < 0 || y_px >= ibuf->y || y_px < 0)
return;
coordinate = y_px * ibuf->x + x_px;
coordinate = ((size_t)y_px) * ibuf->x + x_px;
if (!BLI_BITMAP_TEST(touched, coordinate)) {
if (compare_len_squared_v3v3(ibuf->rect_float + 4 * coordinate, color, threshold_sq)) {
@ -1386,21 +1386,21 @@ void paint_2d_bucket_fill(
if (!mouse_init || !br) {
/* first case, no image UV, fill the whole image */
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y);
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y, false);
if (do_float) {
for (x_px = 0; x_px < ibuf->x; x_px++) {
for (y_px = 0; y_px < ibuf->y; y_px++) {
blend_color_mix_float(ibuf->rect_float + 4 * (y_px * ibuf->x + x_px),
ibuf->rect_float + 4 * (y_px * ibuf->x + x_px), color_f);
blend_color_mix_float(ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px), color_f);
}
}
}
else {
for (x_px = 0; x_px < ibuf->x; x_px++) {
for (y_px = 0; y_px < ibuf->y; y_px++) {
blend_color_mix_byte((unsigned char *)(ibuf->rect + y_px * ibuf->x + x_px),
(unsigned char *)(ibuf->rect + y_px * ibuf->x + x_px), (unsigned char *)&color_b);
blend_color_mix_byte((unsigned char *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px),
(unsigned char *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px), (unsigned char *)&color_b);
}
}
}
@ -1410,7 +1410,7 @@ void paint_2d_bucket_fill(
* value is within the brush fill threshold from the fill color */
BLI_Stack *stack;
BLI_bitmap *touched;
int coordinate;
size_t coordinate;
int width = ibuf->x;
float image_init[2];
int minx = ibuf->x, miny = ibuf->y, maxx = 0, maxy = 0;
@ -1428,12 +1428,12 @@ void paint_2d_bucket_fill(
}
/* change image invalidation method later */
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y);
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y, false);
stack = BLI_stack_new(sizeof(int), __func__);
touched = BLI_BITMAP_NEW(ibuf->x * ibuf->y, "bucket_fill_bitmap");
stack = BLI_stack_new(sizeof(size_t), __func__);
touched = BLI_BITMAP_NEW(((size_t)ibuf->x) * ibuf->y, "bucket_fill_bitmap");
coordinate = (y_px * ibuf->x + x_px);
coordinate = (((size_t)y_px) * ibuf->x + x_px);
if (do_float) {
copy_v4_v4(pixel_color, ibuf->rect_float + 4 * coordinate);
@ -1566,7 +1566,7 @@ void paint_2d_gradient_fill(
do_float = (ibuf->rect_float != NULL);
/* this will be substituted by something else when selection is available */
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y);
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y, false);
if (do_float) {
for (x_px = 0; x_px < ibuf->x; x_px++) {
@ -1590,8 +1590,8 @@ void paint_2d_gradient_fill(
/* convert to premultiplied */
mul_v3_fl(color_f, color_f[3]);
color_f[3] *= br->alpha;
IMB_blend_color_float(ibuf->rect_float + 4 * (y_px * ibuf->x + x_px),
ibuf->rect_float + 4 * (y_px * ibuf->x + x_px),
IMB_blend_color_float(ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px),
ibuf->rect_float + 4 * (((size_t)y_px) * ibuf->x + x_px),
color_f, br->blend);
}
}
@ -1619,8 +1619,8 @@ void paint_2d_gradient_fill(
linearrgb_to_srgb_v3_v3(color_f, color_f);
rgba_float_to_uchar((unsigned char *)&color_b, color_f);
((unsigned char *)&color_b)[3] *= br->alpha;
IMB_blend_color_byte((unsigned char *)(ibuf->rect + y_px * ibuf->x + x_px),
(unsigned char *)(ibuf->rect + y_px * ibuf->x + x_px),
IMB_blend_color_byte((unsigned char *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px),
(unsigned char *)(ibuf->rect + ((size_t)y_px) * ibuf->x + x_px),
(unsigned char *)&color_b, br->blend);
}
}

View File

@ -1501,10 +1501,10 @@ static int project_paint_undo_subtiles(const TileInfo *tinf, int tx, int ty)
if (generate_tile) {
volatile void *undorect;
if (tinf->masked) {
undorect = image_undo_push_tile(pjIma->ima, pjIma->ibuf, tinf->tmpibuf, tx, ty, &pjIma->maskRect[tile_index], &pjIma->valid[tile_index], true);
undorect = image_undo_push_tile(pjIma->ima, pjIma->ibuf, tinf->tmpibuf, tx, ty, &pjIma->maskRect[tile_index], &pjIma->valid[tile_index], true, false);
}
else {
undorect = image_undo_push_tile(pjIma->ima, pjIma->ibuf, tinf->tmpibuf, tx, ty, NULL, &pjIma->valid[tile_index], true);
undorect = image_undo_push_tile(pjIma->ima, pjIma->ibuf, tinf->tmpibuf, tx, ty, NULL, &pjIma->valid[tile_index], true, false);
}
pjIma->ibuf->userflags |= IB_BITMAPDIRTY;

View File

@ -145,7 +145,7 @@ typedef struct ImagePaintPartialRedraw {
int image_texture_paint_poll(struct bContext *C);
void *image_undo_find_tile(struct Image *ima, struct ImBuf *ibuf, int x_tile, int y_tile, unsigned short **mask, bool validate);
void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile, unsigned short **, bool **valid, bool proj);
void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile, unsigned short **, bool **valid, bool proj, bool find_prev);
void image_undo_remove_masks(void);
void image_undo_init_locks(void);
void image_undo_end_locks(void);

View File

@ -2406,7 +2406,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
const bool b = RNA_boolean_get(op->ptr, "invert_b");
const bool a = RNA_boolean_get(op->ptr, "invert_a");
int i;
size_t i;
if (ibuf == NULL) /* TODO: this should actually never happen, but does for render-results -> cleanup */
return OPERATOR_CANCELLED;
@ -2417,13 +2417,13 @@ static int image_invert_exec(bContext *C, wmOperator *op)
/* not strictly needed, because we only imapaint_dirty_region to invalidate all tiles
* but better do this right in case someone copies this for a tool that uses partial redraw better */
ED_imapaint_clear_partial_redraw();
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y);
ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y, false);
}
/* TODO: make this into an IMB_invert_channels(ibuf,r,g,b,a) method!? */
if (ibuf->rect_float) {
float *fp = (float *) ibuf->rect_float;
for (i = ibuf->x * ibuf->y; i > 0; i--, fp += 4) {
for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, fp += 4) {
if (r) fp[0] = 1.0f - fp[0];
if (g) fp[1] = 1.0f - fp[1];
if (b) fp[2] = 1.0f - fp[2];
@ -2437,7 +2437,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
else if (ibuf->rect) {
char *cp = (char *) ibuf->rect;
for (i = ibuf->x * ibuf->y; i > 0; i--, cp += 4) {
for (i = ((size_t)ibuf->x) * ibuf->y; i > 0; i--, cp += 4) {
if (r) cp[0] = 255 - cp[0];
if (g) cp[1] = 255 - cp[1];
if (b) cp[2] = 255 - cp[2];