Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/filter.c')
-rw-r--r--source/blender/imbuf/intern/filter.c137
1 files changed, 90 insertions, 47 deletions
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index ef445239491..26ced49a333 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -203,54 +203,97 @@ void imb_filterx(struct ImBuf *ibuf)
}
}
-void IMB_filterN(ImBuf *out, ImBuf *in)
+static void imb_filterN(ImBuf *out, ImBuf *in)
{
- register char *row1, *row2, *row3;
- register char *cp, *r11, *r13, *r21, *r23, *r31, *r33;
- int rowlen, x, y;
-
- rowlen = in->x;
-
- /* generate 32-bit version for float images if it is not already generated by other space */
- if (in->rect == NULL)
- IMB_rect_from_float(in);
+ BLI_assert(out->channels == in->channels);
+ BLI_assert(out->x == in->x && out->y == out->y);
+
+ const int channels = in->channels;
+ const int rowlen = in->x;
- for (y = 0; y < in->y; y++) {
- /* setup rows */
- row2 = (char *)(in->rect + y * rowlen);
- row1 = (y == 0) ? row2 : row2 - 4 * rowlen;
- row3 = (y == in->y - 1) ? row2 : row2 + 4 * rowlen;
-
- cp = (char *)(out->rect + y * rowlen);
-
- for (x = 0; x < rowlen; x++) {
- if (x == 0) {
- r11 = row1;
- r21 = row2;
- r31 = row3;
- }
- else {
- r11 = row1 - 4;
- r21 = row2 - 4;
- r31 = row3 - 4;
- }
+ if (in->rect && out->rect) {
+ for (int y = 0; y < in->y; y++) {
+ /* setup rows */
+ const char *row2 = (const char *)in->rect + y * channels * rowlen;
+ const char *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
+ const char *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
+
+ char *cp = (char *)out->rect + y * channels * rowlen;
+
+ for (int x = 0; x < rowlen; x++) {
+ const char *r11, *r13, *r21, *r23, *r31, *r33;
+
+ if (x == 0) {
+ r11 = row1;
+ r21 = row2;
+ r31 = row3;
+ }
+ else {
+ r11 = row1 - channels;
+ r21 = row2 - channels;
+ r31 = row3 - channels;
+ }
- if (x == rowlen - 1) {
- r13 = row1;
- r23 = row2;
- r33 = row3;
- }
- else {
- r13 = row1 + 4;
- r23 = row2 + 4;
- r33 = row3 + 4;
+ if (x == rowlen - 1) {
+ r13 = row1;
+ r23 = row2;
+ r33 = row3;
+ }
+ else {
+ r13 = row1 + channels;
+ r23 = row2 + channels;
+ r33 = row3 + channels;
+ }
+
+ cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) >> 4;
+ cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) >> 4;
+ cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) >> 4;
+ cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) >> 4;
+ cp += channels; row1 += channels; row2 += channels; row3 += channels;
}
+ }
+ }
+
+ if (in->rect_float && out->rect_float) {
+ for (int y = 0; y < in->y; y++) {
+ /* setup rows */
+ const float *row2 = (const float *)in->rect_float + y * channels * rowlen;
+ const float *row1 = (y == 0) ? row2 : row2 - channels * rowlen;
+ const float *row3 = (y == in->y - 1) ? row2 : row2 + channels * rowlen;
+
+ float *cp = (float *)out->rect_float + y * channels * rowlen;
+
+ for (int x = 0; x < rowlen; x++) {
+ const float *r11, *r13, *r21, *r23, *r31, *r33;
- cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) >> 4;
- cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) >> 4;
- cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) >> 4;
- cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) >> 4;
- cp += 4; row1 += 4; row2 += 4; row3 += 4;
+ if (x == 0) {
+ r11 = row1;
+ r21 = row2;
+ r31 = row3;
+ }
+ else {
+ r11 = row1 - channels;
+ r21 = row2 - channels;
+ r31 = row3 - channels;
+ }
+
+ if (x == rowlen - 1) {
+ r13 = row1;
+ r23 = row2;
+ r33 = row3;
+ }
+ else {
+ r13 = row1 + channels;
+ r23 = row2 + channels;
+ r33 = row3 + channels;
+ }
+
+ cp[0] = (r11[0] + 2 * row1[0] + r13[0] + 2 * r21[0] + 4 * row2[0] + 2 * r23[0] + r31[0] + 2 * row3[0] + r33[0]) * (1.0f / 16.0f);
+ cp[1] = (r11[1] + 2 * row1[1] + r13[1] + 2 * r21[1] + 4 * row2[1] + 2 * r23[1] + r31[1] + 2 * row3[1] + r33[1]) * (1.0f / 16.0f);
+ cp[2] = (r11[2] + 2 * row1[2] + r13[2] + 2 * r21[2] + 4 * row2[2] + 2 * r23[2] + r31[2] + 2 * row3[2] + r33[2]) * (1.0f / 16.0f);
+ cp[3] = (r11[3] + 2 * row1[3] + r13[3] + 2 * r21[3] + 4 * row2[3] + 2 * r23[3] + r31[3] + 2 * row3[3] + r33[3]) * (1.0f / 16.0f);
+ cp += channels; row1 += channels; row2 += channels; row3 += channels;
+ }
}
}
}
@@ -477,8 +520,8 @@ void IMB_remakemipmap(ImBuf *ibuf, int use_filter)
if (ibuf->mipmap[curmap]) {
if (use_filter) {
- ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect);
- IMB_filterN(nbuf, hbuf);
+ ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
+ imb_filterN(nbuf, hbuf);
imb_onehalf_no_alloc(ibuf->mipmap[curmap], nbuf);
IMB_freeImBuf(nbuf);
}
@@ -514,8 +557,8 @@ void IMB_makemipmap(ImBuf *ibuf, int use_filter)
while (curmap < IMB_MIPMAP_LEVELS) {
if (use_filter) {
- ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, 32, IB_rect);
- IMB_filterN(nbuf, hbuf);
+ ImBuf *nbuf = IMB_allocImBuf(hbuf->x, hbuf->y, hbuf->planes, hbuf->flags);
+ imb_filterN(nbuf, hbuf);
ibuf->mipmap[curmap] = IMB_onehalf(nbuf);
IMB_freeImBuf(nbuf);
}