#ifndef UNSUPPORTED static void convert_3d(struct filter *f, int *x1, int *y1) { struct threeddata *data = (struct threeddata *) f->data; int y; int x = *x1; unsigned int inp; unsigned int height = data->height; register CONST spixel_t *input; if (x >= f->childimage->width - 5 || x < 0 || *y1 > f->childimage->height) { *x1 += *y1 / 2; return; } if (x < 0) x = 0; for (y = f->childimage->height - 3; y >= 0; y--) { int d; input = ((spixel_t *) f->childimage->currlines[y] + y / 2); inp = (input[x] + input[x + 1] + input[x + 2] + input[x + 3] + input[x + 4] + input[x + 5]); input = ((spixel_t *) f->childimage->currlines[y + 1] + y / 2); inp += (input[x] + input[x + 1] + input[x + 2] + input[x + 3] + input[x + 4] + input[x + 5]); input = ((spixel_t *) f->childimage->currlines[y + 2] + y / 2); inp += (input[x] + input[x + 1] + input[x + 2] + input[x + 3] + input[x + 4] + input[x + 5]); d = y - (inp / 16 > height ? height : inp / 16); if (d <= *y1) { *y1 = y; *x1 = x + y / 2; return; } } *x1 += *y1 / 2; return; } static void convertup_3d(struct filter *f, int *x1, int *y1) { struct threeddata *data = (struct threeddata *) f->data; int y = *y1; int x = *x1; unsigned int inp; unsigned int height = data->height; register CONST spixel_t *input; if (x >= f->childimage->width - 5) x = f->childimage->width - 6; if (y >= f->childimage->height - 3) y = f->childimage->height - 3; if (x < 0) x = 0; if (y < 0) y = 0; input = ((spixel_t *) f->childimage->currlines[y] + y / 2); inp = (input[x] + input[x + 1] + input[x + 2] + input[x + 3] + input[x + 4] + input[x + 5]); input = ((spixel_t *) f->childimage->currlines[y + 1] + y / 2); inp += (input[x] + input[x + 1] + input[x + 2] + input[x + 3] + input[x + 4] + input[x + 5]); input = ((spixel_t *) f->childimage->currlines[y + 2] + y / 2); inp += (input[x] + input[x + 1] + input[x + 2] + input[x + 3] + input[x + 4] + input[x + 5]); *x1 -= *y1 / 2; *y1 = y - (inp / 16 > height ? height : inp / 16); } static void do_3d(void *dataptr, struct taskinfo *task, int r1, int r2) { struct filter *RESTRICT f = (struct filter *) dataptr; unsigned int y; int maxinp = 0; unsigned int x; unsigned int end; unsigned int sum; spixel_t CONST *RESTRICT input; unsigned int *RESTRICT lengths; unsigned int *RESTRICT sums; unsigned int *RESTRICT relsums; struct threeddata *data = (struct threeddata *) f->data; /* Copy to local variables to improve cse and memory references. */ unsigned int height = data->height; unsigned int stereogrammode = data->stereogrammode; unsigned int colheight = data->colheight; unsigned int midcolor = data->midcolor; unsigned int darkcolor = data->darkcolor; CONST unsigned int *RESTRICT pixels = data->pixels; cpixel_t *RESTRICT * RESTRICT currlines = (cpixel_t * RESTRICT * RESTRICT) f->image->currlines; struct inp { int max; unsigned int down; } *inpdata; #ifdef HAVE_ALLOCA1 lengths = (unsigned int *) alloca(sizeof(unsigned int) * f->image->width); inpdata = (struct inp *) alloca(sizeof(struct inp) * (f->image->width + 2)); sums = (unsigned int *) alloca(sizeof(unsigned int) * (f->image->width + 2) * 2); #else lengths = (unsigned int *) malloc(sizeof(unsigned int) * f->image->width); inpdata = (struct inp *) malloc(sizeof(struct inp) * (f->image->width + 2)); sums = (unsigned int *) malloc(sizeof(unsigned int) * (f->image->width + 2) * 2); #endif for (x = 0; x < (unsigned int) f->image->width; x++) lengths[x] = f->image->height - 1, sums[x * 2 + 0] = 0, sums[x * 2 + 1] = 0, inpdata[x].max = 0; sums[x * 2 + 0] = 0, sums[x * 2 + 1] = 0, inpdata[x].max = 0; inpdata[x + 1].max = 0; end = r2; for (y = f->childimage->height - 2; y > 0;) { y--; input = ((spixel_t *) f->childimage->currlines[y] + y / 2); x = r1; relsums = sums + (y & 1); /* Fix boundary cases. */ /*relsums[0] = relsums[1]; relsums[end*2-1] = relsums[end*2-2]; */ inpdata[end + 1] = inpdata[end] = inpdata[end - 1]; sum = input[x] + input[x + 1] + input[x + 2] + input[x + 3] + input[x + 4] + input[x + 5]; while (x < end) { unsigned int inp; unsigned int d; /* Average pixel values of 5*3 square to get nicer shapes. */ sum += input[x + 6] - input[x]; inp = sum + sums[x * 2 + 1] + sums[x * 2]; relsums[x * 2] = sum; inpdata[x].down = inp; /* Calculate shades. */ maxinp = inpdata[x + 2].max; if ((int) inp > maxinp) inpdata[x].max = inp - 32; else inpdata[x].max = maxinp - 32; /* caluclate top of mountain. */ d = inp / 16; d = y - (d > height ? height : d); /* Underflow */ if (d > 65535U) d = 0; if (d < lengths[x]) { int y1; unsigned int color; if (stereogrammode) color = pixels[y]; else if (inp / 16 > height) /*Red thinks on the top. */ color = pixels[inp / 16 >= colheight ? colheight : inp / 16]; else { int c; /* Simple shading model. Depends only on the preceding voxel. */ c = ((int) inpdata[x + 2].down - (int) inp) / 8; /* Get shades. */ color = ((int) inp > maxinp ? midcolor : darkcolor) - c; color = pixels[color < 65535 ? (color < height ? color : height) : 0]; } for (y1 = lengths[x]; y1 >= (int) d; y1--) { p_setp(currlines[y1], x, color); } lengths[x] = d; } x++; } } #ifndef HAVE_ALLOCA1 free(lengths); free(inpdata); free(sums); #endif } #endif #undef do_3d #undef convert_3d #undef convertup_3d