77 typedef float WorkType;
78 typedef float StoreType;
79 static const WorkType source_max = 1.0f;
80 static const WorkType filter_max = 1.0f;
109 filter_row(StoreType dest[],
int dest_len,
110 const StoreType source[],
int source_len,
112 const WorkType filter[],
113 float filter_width) {
122 filter_width /= scale;
127 for (
int dest_x = 0; dest_x < dest_len; dest_x++) {
129 float center = (dest_x + 0.5f) / scale - 0.5f;
134 int left = max((
int)cfloor(center - filter_width), 0);
135 int right = min((
int)cceil(center + filter_width), source_len - 1);
139 int right_center = (int)cceil(center);
141 WorkType net_weight = 0;
142 WorkType net_value = 0;
149 for (source_x = left; source_x < right_center; source_x++) {
150 index = (int)(iscale * (center - source_x) + 0.5f);
151 net_value += filter[index] * source[source_x];
152 net_weight += filter[index];
155 for (; source_x <= right; source_x++) {
156 index = (int)(iscale * (source_x - center) + 0.5f);
157 net_value += filter[index] * source[source_x];
158 net_weight += filter[index];
161 if (net_weight > 0) {
162 dest[dest_x] = (StoreType)(net_value / net_weight);
173 filter_sparse_row(StoreType dest[], StoreType dest_weight[],
int dest_len,
174 const StoreType source[],
const StoreType source_weight[],
int source_len,
176 const WorkType filter[],
177 float filter_width) {
186 filter_width /= scale;
191 for (
int dest_x = 0; dest_x < dest_len; dest_x++) {
193 float center = (dest_x + 0.5f) / scale - 0.5f;
198 int left = max((
int)cfloor(center - filter_width), 0);
199 int right = min((
int)cceil(center + filter_width), source_len - 1);
203 int right_center = (int)cceil(center);
205 WorkType net_weight = 0;
206 WorkType net_value = 0;
213 for (source_x = left; source_x < right_center; source_x++) {
214 index = (int)(iscale * (center - source_x) + 0.5f);
215 net_value += filter[index] * source[source_x] * source_weight[source_x];
216 net_weight += filter[index] * source_weight[source_x];
219 for (; source_x <= right; source_x++) {
220 index = (int)(iscale * (source_x - center) + 0.5f);
221 net_value += filter[index] * source[source_x] * source_weight[source_x];
222 net_weight += filter[index] * source_weight[source_x];
225 if (net_weight > 0) {
226 dest[dest_x] = (StoreType)(net_value / net_weight);
230 dest_weight[dest_x] = (StoreType)net_weight;
246 typedef void FilterFunction(
float scale,
float width,
247 WorkType *&filter,
float &filter_width);
250 box_filter_impl(
float scale,
float width,
251 WorkType *&filter,
float &filter_width) {
257 fscale = 1.0 / scale;
265 filter_width = width;
266 int actual_width = (int)cceil((filter_width + 1) * fscale) + 1;
268 filter = (WorkType *)PANDA_MALLOC_ARRAY(actual_width *
sizeof(WorkType));
270 for (
int i = 0; i < actual_width; i++) {
271 filter[i] = (i <= filter_width * fscale) ? filter_max : 0;
276 gaussian_filter_impl(
float scale,
float width,
277 WorkType *&filter,
float &filter_width) {
283 fscale = 1.0 / scale;
292 float sigma = width/2;
293 filter_width = 3.0 * sigma;
294 int actual_width = (int)cceil((filter_width + 1) * fscale);
302 filter = (WorkType *)PANDA_MALLOC_ARRAY(actual_width *
sizeof(WorkType));
303 float div = 2 * sigma * sigma;
305 for (
int i = 0; i < actual_width; i++) {
306 float x = i / fscale;
307 filter[i] = (WorkType)(filter_max * exp(-x*x / div));
339 #define FUNCTION_NAME filter_red_xy 340 #define IMAGETYPE PNMImage 341 #define ASIZE get_x_size 342 #define BSIZE get_y_size 343 #define GETVAL(a, b, channel) get_red(a, b) 344 #define SETVAL(a, b, channel, v) set_red(a, b, v) 353 #define FUNCTION_NAME filter_green_xy 354 #define IMAGETYPE PNMImage 355 #define ASIZE get_x_size 356 #define BSIZE get_y_size 357 #define GETVAL(a, b, channel) get_green(a, b) 358 #define SETVAL(a, b, channel, v) set_green(a, b, v) 367 #define FUNCTION_NAME filter_blue_xy 368 #define IMAGETYPE PNMImage 369 #define ASIZE get_x_size 370 #define BSIZE get_y_size 371 #define GETVAL(a, b, channel) get_blue(a, b) 372 #define SETVAL(a, b, channel, v) set_blue(a, b, v) 381 #define FUNCTION_NAME filter_gray_xy 382 #define IMAGETYPE PNMImage 383 #define ASIZE get_x_size 384 #define BSIZE get_y_size 385 #define GETVAL(a, b, channel) get_bright(a, b) 386 #define SETVAL(a, b, channel, v) set_xel(a, b, v) 395 #define FUNCTION_NAME filter_alpha_xy 396 #define IMAGETYPE PNMImage 397 #define ASIZE get_x_size 398 #define BSIZE get_y_size 399 #define GETVAL(a, b, channel) get_alpha(a, b) 400 #define SETVAL(a, b, channel, v) set_alpha(a, b, v) 412 #define FUNCTION_NAME filter_red_yx 413 #define IMAGETYPE PNMImage 414 #define ASIZE get_y_size 415 #define BSIZE get_x_size 416 #define GETVAL(a, b, channel) get_red(b, a) 417 #define SETVAL(a, b, channel, v) set_red(b, a, v) 426 #define FUNCTION_NAME filter_green_yx 427 #define IMAGETYPE PNMImage 428 #define ASIZE get_y_size 429 #define BSIZE get_x_size 430 #define GETVAL(a, b, channel) get_green(b, a) 431 #define SETVAL(a, b, channel, v) set_green(b, a, v) 440 #define FUNCTION_NAME filter_blue_yx 441 #define IMAGETYPE PNMImage 442 #define ASIZE get_y_size 443 #define BSIZE get_x_size 444 #define GETVAL(a, b, channel) get_blue(b, a) 445 #define SETVAL(a, b, channel, v) set_blue(b, a, v) 454 #define FUNCTION_NAME filter_gray_yx 455 #define IMAGETYPE PNMImage 456 #define ASIZE get_y_size 457 #define BSIZE get_x_size 458 #define GETVAL(a, b, channel) get_bright(b, a) 459 #define SETVAL(a, b, channel, v) set_xel(b, a, v) 468 #define FUNCTION_NAME filter_alpha_yx 469 #define IMAGETYPE PNMImage 470 #define ASIZE get_y_size 471 #define BSIZE get_x_size 472 #define GETVAL(a, b, channel) get_alpha(b, a) 473 #define SETVAL(a, b, channel, v) set_alpha(b, a, v) 487 float width, FilterFunction *make_filter) {
499 filter_gray_xy(dest, source, width, make_filter, 0);
501 filter_red_xy(dest, source, width, make_filter, 0);
502 filter_green_xy(dest, source, width, make_filter, 0);
503 filter_blue_xy(dest, source, width, make_filter, 0);
507 filter_alpha_xy(dest, source, width, make_filter, 0);
512 filter_gray_yx(dest, source, width, make_filter, 0);
514 filter_red_yx(dest, source, width, make_filter, 0);
515 filter_green_yx(dest, source, width, make_filter, 0);
516 filter_blue_yx(dest, source, width, make_filter, 0);
520 filter_alpha_yx(dest, source, width, make_filter, 0);
533 filter_image(*
this, copy, width, &box_filter_impl);
544 filter_image(*
this, copy, width, &gaussian_filter_impl);
551 #define FUNCTION_NAME filter_pfm_xy 552 #define IMAGETYPE PfmFile 553 #define ASIZE get_x_size 554 #define BSIZE get_y_size 555 #define GETVAL(a, b, channel) get_channel(a, b, channel) 556 #define SETVAL(a, b, channel, v) set_channel(a, b, channel, v) 565 #define FUNCTION_NAME filter_pfm_yx 566 #define IMAGETYPE PfmFile 567 #define ASIZE get_y_size 568 #define BSIZE get_x_size 569 #define GETVAL(a, b, channel) get_channel(b, a, channel) 570 #define SETVAL(a, b, channel, v) set_channel(b, a, channel, v) 580 #define FUNCTION_NAME filter_pfm_sparse_xy 581 #define IMAGETYPE PfmFile 582 #define ASIZE get_x_size 583 #define BSIZE get_y_size 584 #define HASVAL(a, b) has_point(a, b) 585 #define GETVAL(a, b, channel) get_channel(a, b, channel) 586 #define SETVAL(a, b, channel, v) set_channel(a, b, channel, v) 596 #define FUNCTION_NAME filter_pfm_sparse_yx 597 #define IMAGETYPE PfmFile 598 #define ASIZE get_y_size 599 #define BSIZE get_x_size 600 #define HASVAL(a, b) has_point(b, a) 601 #define GETVAL(a, b, channel) get_channel(b, a, channel) 602 #define SETVAL(a, b, channel, v) set_channel(b, a, channel, v) 617 float width, FilterFunction *make_filter) {
623 for (
int ci = 0; ci < num_channels; ++ci) {
624 filter_pfm_sparse_xy(dest, source, width, make_filter, ci);
628 for (
int ci = 0; ci < num_channels; ++ci) {
629 filter_pfm_sparse_yx(dest, source, width, make_filter, ci);
635 for (
int ci = 0; ci < num_channels; ++ci) {
636 filter_pfm_xy(dest, source, width, make_filter, ci);
640 for (
int ci = 0; ci < num_channels; ++ci) {
641 filter_pfm_yx(dest, source, width, make_filter, ci);
655 filter_image(*
this, copy, width, &box_filter_impl);
666 filter_image(*
this, copy, width, &gaussian_filter_impl);
673 int x,
int y,
float x_contrib,
float y_contrib,
674 LColorf &color,
float &pixel_count) {
676 float contrib = x_contrib * y_contrib;
678 pixel_count += contrib;
682 box_filter_line(
const PNMImage &image,
683 float x0,
int y,
float x1,
float y_contrib,
684 LColorf &color,
float &pixel_count) {
687 box_filter_xel(image, x, y, (
float)(x+1)-x0, y_contrib,
690 int x_last = (int)x1;
695 box_filter_xel(image, x, y, 1.0f, y_contrib,
701 float x_contrib = x1 - (float)x_last;
702 if (x_contrib > 0.0001f && x < image.
get_x_size()) {
703 box_filter_xel(image, x, y, x_contrib, y_contrib,
710 box_filter_region(
const PNMImage &image,
711 float x0,
float y0,
float x1,
float y1) {
712 LColorf color = LColorf::zero();
713 float pixel_count = 0.0f;
715 assert(y0 >= 0 && y1 >= 0);
719 box_filter_line(image, x0, y, x1, (
float)(y+1)-y0,
722 int y_last = (int)y1;
727 box_filter_line(image, x0, y, x1, 1.0f,
733 float y_contrib = y1 - (float)y_last;
734 if (y_contrib > 0.0001f && y < image.
get_y_size()) {
735 box_filter_line(image, x0, y, x1, y_contrib,
741 color /= pixel_count;
761 int to_xoff = xborder / 2;
762 int to_yoff = yborder / 2;
764 float from_x0, from_x1, from_y0, from_y1;
767 float x_scale = (float)from_xs / (
float)to_xs;
768 float y_scale = (float)from_ys / (
float)to_ys;
772 from_y0 = max(0, -to_yoff) * y_scale;
773 for (to_y = max(0, -to_yoff);
776 from_y1 = (to_y+1) * y_scale;
778 from_x0 = max(0, -to_xoff) * x_scale;
779 for (to_x = max(0, -to_xoff);
782 from_x1 = (to_x+1) * x_scale;
786 color = box_filter_region(from,
787 from_x0, from_y0, from_x1, from_y1);
789 set_xel_a(to_xoff + to_x, to_yoff + to_y, color);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
void quick_filter_from(const PNMImage ©, int xborder=0, int yborder=0)
Resizes from the given image, with a fixed radius of 0.5.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void gaussian_filter_from(float radius, const PfmFile ©)
Makes a resized copy of the indicated image into this one using the indicated filter.
LColorf get_xel_a(int x, int y) const
Returns the RGBA color at the indicated pixel.
Defines a pfm file, a 2-d table of floating-point numbers, either 3-component or 1-component,...
void box_filter_from(float radius, const PfmFile ©)
Makes a resized copy of the indicated image into this one using the indicated filter.
void set_xel_a(int x, int y, const LColorf &value)
Changes the RGBA color at the indicated pixel.
bool has_no_data_value() const
Returns whether a "no data" value has been established by set_no_data_value().
void gaussian_filter_from(float radius, const PNMImage ©)
Makes a resized copy of the indicated image into this one using the indicated filter.
void box_filter_from(float radius, const PNMImage ©)
Makes a resized copy of the indicated image into this one using the indicated filter.