static void gauss_rle (GimpDrawable *drawable, gdouble radius, gint pass, gboolean show_progress) { GimpPixelRgn src_rgn, dest_rgn; gint width, height; gint bytes; gint has_alpha; guchar *dest, *dp; guchar *src, *sp; gint *buf, *bb; gint pixels; gint total = 1; gint x1, y1, x2, y2; gint i, row, col, b; gint start, end; gdouble progress, max_progress; gint *curve; gint *sum = NULL; gint val; gint length; gint initial_p, initial_m; gdouble std_dev; if (radius <= 0.0) return; gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); width = (x2 - x1); height = (y2 - y1); if (width < 1 || height < 1) return; bytes = drawable->bpp; has_alpha = gimp_drawable_has_alpha(drawable->drawable_id); buf = g_new (gint, MAX (width, height) * 2); /* allocate buffers for source and destination pixels */ src = g_new (guchar, MAX (width, height) * bytes); dest = g_new (guchar, MAX (width, height) * bytes); gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, TRUE); progress = 0.0; max_progress = 2 * width * height; /* First the vertical pass */ radius = fabs (radius) + 1.0; std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0))); curve = make_curve (std_dev, &length); sum = g_new (gint, 2 * length + 1); sum[0] = 0; for (i = 1; i <= length*2; i++) sum[i] = curve[i-length-1] + sum[i-1]; sum += length; total = sum[length] - sum[-length]; for (col = 0; col < width; col++) { gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, (y2 - y1)); if (has_alpha) multiply_alpha (src, height, bytes); sp = src; dp = dest; for (b = 0; b < bytes; b++) { initial_p = sp[b]; initial_m = sp[(height-1) * bytes + b]; /* Determine a run-length encoded version of the row */ run_length_encode (sp + b, buf, bytes, height); for (row = 0; row < height; row++) { start = (row < length) ? -row : -length; end = (height <= (row + length) ? (height - row - 1) : length); val = 0; i = start; bb = buf + (row + i) * 2; if (start != -length) val += initial_p * (sum[start] - sum[-length]); while (i < end) { pixels = bb[0]; i += pixels; if (i > end) i = end; val += bb[1] * (sum[i] - sum[start]); bb += (pixels * 2); start = i; } if (end != length) val += initial_m * (sum[length] - sum[end]); dp[row * bytes + b] = val / total; } } if (has_alpha) separate_alpha (dest, height, bytes); gimp_pixel_rgn_set_col (&dest_rgn, dest, col + x1, y1, (y2 - y1)); if (show_progress) { progress += height; if ((col % 32) == 0) gimp_progress_update (0.5 * (pass + (progress / max_progress))); } } /* prepare for the horizontal pass */ gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, TRUE); /* Now the horizontal pass */ for (row = 0; row < height; row++) { gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, (x2 - x1)); if (has_alpha) multiply_alpha (src, width, bytes); sp = src; dp = dest; for (b = 0; b < bytes; b++) { initial_p = sp[b]; initial_m = sp[(width-1) * bytes + b]; /* Determine a run-length encoded version of the row */ run_length_encode (sp + b, buf, bytes, width); for (col = 0; col < width; col++) { start = (col < length) ? -col : -length; end = (width <= (col + length)) ? (width - col - 1) : length; val = 0; i = start; bb = buf + (col + i) * 2; if (start != -length) val += initial_p * (sum[start] - sum[-length]); while (i < end) { pixels = bb[0]; i += pixels; if (i > end) i = end; val += bb[1] * (sum[i] - sum[start]); bb += (pixels * 2); start = i; } if (end != length) val += initial_m * (sum[length] - sum[end]); dp[col * bytes + b] = val / total; } } if (has_alpha) separate_alpha (dest, width, bytes); gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, (x2 - x1)); if (show_progress) { progress += width; if ((row % 32) == 0) gimp_progress_update (0.5 * (pass + (progress / max_progress))); } } /* merge the shadow, update the drawable */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); /* free buffers */ g_free (buf); g_free (src); g_free (dest); }
static void c2g_region (GimpPixelRgn *srcPR, GimpPixelRgn *destPR, gint bytes, /* Bytes per pixel */ gdouble radius, gdouble amount_p, gdouble gamma_p, gint x1, /* Corners of subregion */ gint x2, gint y1, gint y2, gboolean show_progress) { guchar *src; guchar *dest; guchar *bigsrc; guchar *bigdest; guchar *tmpdest; gint width = x2 - x1; gint height = y2 - y1; gdouble *cmatrix = NULL; gint cmatrix_length; gdouble *ctable; gint row, col, idx; gint w = c2g_params.radius+10; gdouble amount = c2g_params.amount; gdouble gamma = c2g_params.gamma; if (show_progress) gimp_progress_init (_("Blurring...")); iir_init(c2g_params.radius); /* allocate buffers */ src = g_new (guchar, MAX (width, height) * bytes); dest = g_new (guchar, MAX (width, height) * bytes); iir.p = g_new(gdouble, MAX (width, height)+2*w); bigsrc = g_new(guchar, width * height * bytes); bigdest = g_new(guchar, width * height * bytes); tmpdest = g_new(guchar, width * height * bytes); if (show_progress) gimp_progress_init (_("Colour converting...")); // 1. Calculate Nayatani Grey and Blur in LAB gimp_pixel_rgn_get_rect (srcPR, bigsrc, x1, y1, width, height); extract_lab(bigsrc, bytes, width * height, bigdest); nayatani(bigdest,bytes,width * height, bigdest); gimp_pixel_rgn_set_rect (destPR, bigdest, x1, y1, width, height); // 2. Make a blur of Grey LAB for (row = 0, idx=0; row < height; row++, idx+=width) { gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width); blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes); gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width); } for (col = 0; col < width; col++) { gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height); blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes); gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height); if (show_progress && col % 8 == 0) gimp_progress_update ((gdouble) col / (3 * width) + 0.33); } // 3. Convert grey and blur back to RGB. compose_lab(bigdest, width * height, bytes, bigdest); // bigdest=greyRGB gimp_pixel_rgn_get_rect (destPR, bigsrc, x1, y1, width, height); compose_lab(bigsrc, width * height, bytes, bigsrc); // bigsrc= blurgreyRGB // 4. Blur Colour RGB and write into destPR gimp_pixel_rgn_get_rect (srcPR, tmpdest, x1, y1, width, height); gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height); for (row = 0, idx=0; row < height; row++, idx+=width) { gimp_pixel_rgn_get_row (destPR, src, x1, y1 + row, width); blur_line (ctable, cmatrix, cmatrix_length, src, dest, width, bytes); gimp_pixel_rgn_set_row (destPR, dest, x1, y1 + row, width); } for (col = 0; col < width; col++) { gimp_pixel_rgn_get_col (destPR, src, x1 + col, y1, height); blur_line (ctable, cmatrix, cmatrix_length, src, dest, height, bytes); gimp_pixel_rgn_set_col (destPR, dest, x1 + col, y1, height); if (show_progress && col % 8 == 0) gimp_progress_update ((gdouble) col / (3 * width) + 0.33); } // destPR = blur colour RGB chromaunsharp( srcPR, destPR, bigdest, bigsrc, bytes, x1, y1, width, height, amount, gamma, tmpdest ); compose_lab(tmpdest, width * height, bytes, tmpdest); // tmpdest has unsharp gimp_pixel_rgn_set_rect (destPR, tmpdest, x1, y1, width, height); if (show_progress) gimp_progress_update (0.0); g_free (bigsrc); g_free (bigdest); g_free (tmpdest); g_free (iir.p); g_free (dest); g_free (src); }
static void neon (GimpDrawable *drawable, gdouble radius, gdouble amount, GimpPreview *preview) { GimpPixelRgn src_rgn, dest_rgn; gint width, height; gint bytes, bpp; gboolean has_alpha; guchar *dest; guchar *src, *src2, *sp_p, *sp_m; gdouble n_p[5], n_m[5]; gdouble d_p[5], d_m[5]; gdouble bd_p[5], bd_m[5]; gdouble *val_p, *val_m, *vp, *vm; gint x1, y1, x2, y2; gint i, j; gint row, col, b; gint terms; gint progress = 0, max_progress = 1; gint initial_p[4]; gint initial_m[4]; gdouble std_dev; guchar *preview_buffer1 = NULL; guchar *preview_buffer2 = NULL; if (preview) { gimp_preview_get_position (preview, &x1, &y1); gimp_preview_get_size (preview, &width, &height); x2 = x1 + width; y2 = y1 + height; } else { gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); width = (x2 - x1); height = (y2 - y1); } if (radius < 1.0) return; bytes = drawable->bpp; bpp = bytes; has_alpha = gimp_drawable_has_alpha(drawable->drawable_id); if (has_alpha) bpp--; val_p = g_new (gdouble, MAX (width, height) * bytes); val_m = g_new (gdouble, MAX (width, height) * bytes); src = g_new (guchar, MAX (width, height) * bytes); src2 = g_new (guchar, MAX (width, height) * bytes); dest = g_new (guchar, MAX (width, height) * bytes); gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE); if (preview) { preview_buffer1 = g_new (guchar, width * height * bytes); preview_buffer2 = g_new (guchar, width * height * bytes); } else { gimp_pixel_rgn_init (&dest_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, TRUE); progress = 0; max_progress = (radius < 1.0 ) ? 0 : width * height * radius * 2; } /* First the vertical pass */ radius = fabs (radius) + 1.0; std_dev = sqrt (-(radius * radius) / (2 * log (1.0 / 255.0))); /* derive the constants for calculating the gaussian from the std dev */ find_constants (n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev); for (col = 0; col < width; col++) { memset (val_p, 0, height * bytes * sizeof (gdouble)); memset (val_m, 0, height * bytes * sizeof (gdouble)); gimp_pixel_rgn_get_col (&src_rgn, src, col + x1, y1, (y2 - y1)); sp_p = src; sp_m = src + (height - 1) * bytes; vp = val_p; vm = val_m + (height - 1) * bytes; /* Set up the first vals */ for (i = 0; i < bytes; i++) { initial_p[i] = sp_p[i]; initial_m[i] = sp_m[i]; } for (row = 0; row < height; row++) { gdouble *vpptr, *vmptr; terms = (row < 4) ? row : 4; for (b = 0; b < bpp; b++) { vpptr = vp + b; vmptr = vm + b; for (i = 0; i <= terms; i++) { *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - d_p[i] * vp[(-i * bytes) + b]; *vmptr += n_m[i] * sp_m[(i * bytes) + b] - d_m[i] * vm[(i * bytes) + b]; } for (j = i; j <= 4; j++) { *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; } } if (has_alpha) { vp[bpp] = sp_p[bpp]; vm[bpp] = sp_m[bpp]; } sp_p += bytes; sp_m -= bytes; vp += bytes; vm -= bytes; } transfer_pixels (val_p, val_m, dest, bytes, height); if (preview) { for (row = 0 ; row < height ; row++) memcpy (preview_buffer1 + (row * width + col) * bytes, dest + bytes * row, bytes); } else { gimp_pixel_rgn_set_col (&dest_rgn, dest, col + x1, y1, (y2 - y1)); progress += height * radius; if ((col % 20) == 0) gimp_progress_update ((double) progress / (double) max_progress); } } /* Now the horizontal pass */ gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE); for (row = 0; row < height; row++) { memset (val_p, 0, width * bytes * sizeof (gdouble)); memset (val_m, 0, width * bytes * sizeof (gdouble)); gimp_pixel_rgn_get_row (&src_rgn, src, x1, row + y1, (x2 - x1)); if (preview) { memcpy (src2, preview_buffer1 + row * width * bytes, width * bytes); } else { gimp_pixel_rgn_get_row (&dest_rgn, src2, x1, row + y1, (x2 - x1)); } sp_p = src; sp_m = src + (width - 1) * bytes; vp = val_p; vm = val_m + (width - 1) * bytes; /* Set up the first vals */ for (i = 0; i < bytes; i++) { initial_p[i] = sp_p[i]; initial_m[i] = sp_m[i]; } for (col = 0; col < width; col++) { gdouble *vpptr, *vmptr; terms = (col < 4) ? col : 4; for (b = 0; b < bpp; b++) { vpptr = vp + b; vmptr = vm + b; for (i = 0; i <= terms; i++) { *vpptr += n_p[i] * sp_p[(-i * bytes) + b] - d_p[i] * vp[(-i * bytes) + b]; *vmptr += n_m[i] * sp_m[(i * bytes) + b] - d_m[i] * vm[(i * bytes) + b]; } for (j = i; j <= 4; j++) { *vpptr += (n_p[j] - bd_p[j]) * initial_p[b]; *vmptr += (n_m[j] - bd_m[j]) * initial_m[b]; } } if (has_alpha) { vp[bpp] = sp_p[bpp]; vm[bpp] = sp_m[bpp]; } sp_p += bytes; sp_m -= bytes; vp += bytes; vm -= bytes; } transfer_pixels (val_p, val_m, dest, bytes, width); combine_to_gradient (dest, src2, bytes, width, amount); if (preview) { memcpy (preview_buffer2 + row * width * bytes, dest, width * bytes); } else { gimp_pixel_rgn_set_row (&dest_rgn, dest, x1, row + y1, (x2 - x1)); progress += width * radius; if ((row % 20) == 0) gimp_progress_update ((double) progress / (double) max_progress); } } if (preview) { gimp_preview_draw_buffer (preview, preview_buffer2, width * bytes); g_free (preview_buffer1); g_free (preview_buffer2); } else { gimp_progress_update (1.0); /* now, merge horizontal and vertical into a magnitude */ gimp_pixel_rgn_init (&src_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, TRUE); /* merge the shadow, update the drawable */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); } /* free up buffers */ g_free (val_p); g_free (val_m); g_free (src); g_free (src2); g_free (dest); }
static void do_zcrop (GimpDrawable *drawable, gint32 image_id) { GimpPixelRgn srcPR, destPR; gint width, height, x, y; gint bytes; guchar *buffer; gint8 *killrows; gint8 *killcols; gint32 livingrows, livingcols, destrow, destcol; gint total_area, area; gboolean has_alpha; width = drawable->width; height = drawable->height; bytes = drawable->bpp; total_area = width * height * 4; area = 0; killrows = g_new (gint8, height); killcols = g_new (gint8, width); buffer = g_malloc ((width > height ? width : height) * bytes); /* initialize the pixel regions */ gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); livingrows = 0; for (y = 0; y < height; y++) { gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, width); killrows[y] = TRUE; for (x = 0; x < width * bytes; x += bytes) { if (! colors_equal (buffer, &buffer[x], bytes, has_alpha)) { livingrows++; killrows[y] = FALSE; break; } } area += width; if (y % 20 == 0) gimp_progress_update ((double) area / (double) total_area); } livingcols = 0; for (x = 0; x < width; x++) { gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, height); killcols[x] = TRUE; for (y = 0; y < height * bytes; y += bytes) { if (! colors_equal (buffer, &buffer[y], bytes, has_alpha)) { livingcols++; killcols[x] = FALSE; break; } } area += height; if (x % 20 == 0) gimp_progress_update ((double) area / (double) total_area); } if ((livingcols == 0 || livingrows==0) || (livingcols == width && livingrows == height)) { g_message (_("Nothing to crop.")); g_free (killrows); g_free (killcols); return; } destrow = 0; for (y = 0; y < height; y++) { if (!killrows[y]) { gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, width); gimp_pixel_rgn_set_row (&destPR, buffer, 0, destrow, width); destrow++; } area += width; if (y % 20 == 0) gimp_progress_update ((double) area / (double) total_area); } destcol = 0; gimp_pixel_rgn_init(&srcPR, drawable, 0, 0, width, height, FALSE, TRUE); for (x = 0; x < width; x++) { if (!killcols[x]) { gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, height); gimp_pixel_rgn_set_col (&destPR, buffer, destcol, 0, height); destcol++; } area += height; if (x % 20 == 0) gimp_progress_update ((double) area / (double) total_area); } g_free (buffer); g_free (killrows); g_free (killcols); gimp_progress_update (1.00); gimp_image_undo_group_start (image_id); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_image_crop (image_id, livingcols, livingrows, 0, 0); gimp_image_undo_group_end (image_id); }
static void rotate_drawable (GimpDrawable *drawable) { GimpPixelRgn srcPR, destPR; gint width, height; gint longside; gint bytes; gint row, col; gint offsetx, offsety; gboolean was_lock_alpha = FALSE; guchar *buffer; guchar *src_row, *dest_row; /* initialize */ row = 0; /* Get the size of the input drawable. */ width = drawable->width; height = drawable->height; bytes = drawable->bpp; if (gimp_layer_get_lock_alpha (drawable->drawable_id)) { was_lock_alpha = TRUE; gimp_layer_set_lock_alpha (drawable->drawable_id, FALSE); } if (rotvals.angle == 2) /* we're rotating by 180° */ { gimp_tile_cache_ntiles (2 * (width / gimp_tile_width() + 1)); gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE); src_row = (guchar *) g_malloc (width * bytes); dest_row = (guchar *) g_malloc (width * bytes); for (row = 0; row < height; row++) { gimp_pixel_rgn_get_row (&srcPR, src_row, 0, row, width); for (col = 0; col < width; col++) { memcpy (dest_row + col * bytes, src_row + (width - 1 - col) * bytes, bytes); } gimp_pixel_rgn_set_row (&destPR, dest_row, 0, (height - row - 1), width); if ((row % 5) == 0) gimp_progress_update ((double) row / (double) height); } g_free (src_row); g_free (dest_row); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, 0, 0, width, height); } else /* we're rotating by 90° or 270° */ { (width > height) ? (longside = width) : (longside = height); gimp_layer_resize (drawable->drawable_id, longside, longside, 0, 0); drawable = gimp_drawable_get (drawable->drawable_id); gimp_drawable_flush (drawable); gimp_tile_cache_ntiles ((longside / gimp_tile_width () + 1) + (longside / gimp_tile_height () + 1)); gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, longside, longside, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, longside, longside, TRUE, TRUE); buffer = g_malloc (longside * bytes); if (rotvals.angle == 1) /* we're rotating by 90° */ { for (row = 0; row < height; row++) { gimp_pixel_rgn_get_row (&srcPR, buffer, 0, row, width); gimp_pixel_rgn_set_col (&destPR, buffer, (height - row - 1), 0, width); if ((row % 5) == 0) gimp_progress_update ((double) row / (double) height); } } else /* we're rotating by 270° */ { for (col = 0; col < width; col++) { gimp_pixel_rgn_get_col (&srcPR, buffer, col, 0, height); gimp_pixel_rgn_set_row (&destPR, buffer, 0, (width - col - 1), height); if ((col % 5) == 0) gimp_progress_update ((double) col / (double) width); } } g_free (buffer); gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, 0, 0, height, width); gimp_layer_resize (drawable->drawable_id, height, width, 0, 0); drawable = gimp_drawable_get (drawable->drawable_id); gimp_drawable_flush (drawable); gimp_drawable_update (drawable->drawable_id, 0, 0, height, width); } gimp_drawable_offsets (drawable->drawable_id, &offsetx, &offsety); rotate_compute_offsets (&offsetx, &offsety, gimp_image_width (image_ID), gimp_image_height (image_ID), width, height); gimp_layer_set_offsets (drawable->drawable_id, offsetx, offsety); if (was_lock_alpha) gimp_layer_set_lock_alpha (drawable->drawable_id, TRUE); return; }
static int pr_ass_sub(PyGimpPixelRgn *self, PyObject *v, PyObject *w) { GimpPixelRgn *pr = &(self->pr); PyObject *x, *y; const guchar *buf; Py_ssize_t len, x1, x2, xs, y1, y2, ys; if (w == NULL) { PyErr_SetString(PyExc_TypeError, "can't delete subscripts"); return -1; } if (!PyString_Check(w)) { PyErr_SetString(PyExc_TypeError, "must assign string to subscript"); return -1; } if (!PyTuple_Check(v) || PyTuple_Size(v) != 2) { PyErr_SetString(PyExc_TypeError, "subscript must be a 2-tuple"); return -1; } if (!PyArg_ParseTuple(v, "OO", &x, &y)) return -1; buf = (const guchar *)PyString_AsString(w); len = PyString_Size(w); if (!buf || len > INT_MAX) { return -1; } if (PyInt_Check(x)) { x1 = PyInt_AsSsize_t(x); if (x1 < pr->x || x1 >= pr->x + pr->w) { PyErr_SetString(PyExc_IndexError, "x subscript out of range"); return -1; } if (PyInt_Check(y)) { y1 = PyInt_AsSsize_t(y); if (y1 < pr->y || y1 >= pr->y + pr->h) { PyErr_SetString(PyExc_IndexError, "y subscript out of range"); return -1; } if (len != pr->bpp) { PyErr_SetString(PyExc_TypeError, "string is wrong length"); return -1; } gimp_pixel_rgn_set_pixel(pr, buf, x1, y1); } else if (PySlice_Check(y)) { if (PySlice_GetIndices((PySliceObject *)y, pr->y + pr->h, &y1, &y2, &ys) || y1 >= y2 || ys != 1) { PyErr_SetString(PyExc_IndexError, "invalid y slice"); return -1; } if (y1 == 0) y1 = pr->y; if(y1 < pr->y || y2 < pr->y) { PyErr_SetString(PyExc_IndexError, "y subscript out of range"); return -1; } if (len != pr->bpp * (y2 - y1)) { PyErr_SetString(PyExc_TypeError, "string is wrong length"); return -1; } gimp_pixel_rgn_set_col(pr, buf, x1, y1, y2 - y1); } else { PyErr_SetString(PyExc_IndexError,"invalid y subscript"); return -1; } } else if (PySlice_Check(x)) { if (PySlice_GetIndices((PySliceObject *)x, pr->x + pr->w, &x1, &x2, &xs) || x1 >= x2 || xs != 1) { PyErr_SetString(PyExc_IndexError, "invalid x slice"); return -1; } if(x1 == 0) x1 = pr->x; if(x1 < pr->x || x2 < pr->x) { PyErr_SetString(PyExc_IndexError, "x subscript out of range"); return -1; } if (PyInt_Check(y)) { y1 = PyInt_AsSsize_t(y); if (y1 < pr->y || y1 >= pr->y + pr->h) { PyErr_SetString(PyExc_IndexError, "y subscript out of range"); return -1; } if (len != pr->bpp * (x2 - x1)) { PyErr_SetString(PyExc_TypeError, "string is wrong length"); return -1; } gimp_pixel_rgn_set_row(pr, buf, x1, y1, x2 - x1); } else if (PySlice_Check(y)) { if (PySlice_GetIndices((PySliceObject *)y, pr->y + pr->h, &y1, &y2, &ys) || y1 >= y2 || ys != 1) { PyErr_SetString(PyExc_IndexError, "invalid y slice"); return -1; } if (y1 == 0) y1 = pr->y; if(y1 < pr->y || y2 < pr->y) { PyErr_SetString(PyExc_IndexError, "y subscript out of range"); return -1; } if (len != pr->bpp * (x2 - x1) * (y2 - y1)) { PyErr_SetString(PyExc_TypeError, "string is wrong length"); return -1; } gimp_pixel_rgn_set_rect(pr, buf, x1, y1, x2 - x1, y2 - y1); } else { PyErr_SetString(PyExc_IndexError,"invalid y subscript"); return -1; } } else { PyErr_SetString(PyExc_TypeError, "invalid x subscript"); return -1; } return 0; }