fix some minor bugs in PfmFile::resize(), add config variable quality controls

This commit is contained in:
David Rose 2013-04-20 00:43:24 +00:00
parent cbb55d02e6
commit 5d2b7bc5ea
5 changed files with 41 additions and 17 deletions

View File

@ -935,20 +935,24 @@ add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, boo
case CT_normal3:
{
// Calculate the normal based on two neighboring vertices.
bool flip = reverse_normals;
LPoint3f v[3];
v[0] = pfm.get_point(xi, yi);
if (xi + 1 < pfm.get_x_size()) {
v[1] = v[0];
v[2] = v[0];
if (pfm.has_point(xi + 1, yi)) {
v[1] = pfm.get_point(xi + 1, yi);
} else {
v[1] = v[0];
v[0] = pfm.get_point(xi - 1, yi);
} else if (pfm.has_point(xi - 1, yi)) {
v[1] = pfm.get_point(xi - 1, yi);
flip = !flip;
}
if (yi + 1 < pfm.get_y_size()) {
if (pfm.has_point(xi, yi + 1)) {
v[2] = pfm.get_point(xi, yi + 1);
} else {
v[2] = v[0];
v[0] = pfm.get_point(xi, yi - 1);
} else if (pfm.has_point(xi, yi - 1)) {
v[2] = pfm.get_point(xi, yi - 1);
flip = !flip;
}
LVector3f n = LVector3f::zero();
@ -961,7 +965,7 @@ add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, boo
}
n.normalize();
nassertr(!n.is_nan(), false);
if (reverse_normals) {
if (flip) {
n = -n;
}
if (!transform_vector(n)) {

View File

@ -36,6 +36,20 @@ ConfigVariableBool pfm_reverse_dimensions
"backwards, in the form height width instead of width height, "
"on input. Does not affect output, which is always written width height."));
ConfigVariableBool pfm_resize_gaussian
("pfm-resize-gaussian", true,
PRC_DESC("Specify true to implement PfmFile::resize() with a higher-quality "
"Gaussian filter, or false to implement it with a faster box "
"filter. This just controls the behavior of resize(); you can "
"always call box_filter() or gaussian_filter() explicitly."));
ConfigVariableDouble pfm_resize_radius
("pfm-resize-radius", 1.0,
PRC_DESC("Specify the default filter radius for PfmFile::resize(). "
"This just controls the behavior of resize(); you can "
"always call box_filter() or gaussian_filter() explicitly with "
"a specific radius."));
////////////////////////////////////////////////////////////////////
// Function: init_libpnmimage
// Description: Initializes the library. This must be called at

View File

@ -17,13 +17,15 @@
#include "pandabase.h"
#include "notifyCategoryProxy.h"
#include "configVariableInt.h"
#include "configVariableBool.h"
#include "configVariableDouble.h"
NotifyCategoryDecl(pnmimage, EXPCL_PANDA_PNMIMAGE, EXPTP_PANDA_PNMIMAGE);
extern ConfigVariableBool pfm_force_littleendian;
extern ConfigVariableBool pfm_reverse_dimensions;
extern ConfigVariableBool pfm_resize_gaussian;
extern ConfigVariableDouble pfm_resize_radius;
extern EXPCL_PANDA_PNMIMAGE void init_libpnmimage();

View File

@ -839,13 +839,17 @@ resize(int new_x_size, int new_y_size) {
PfmFile result;
result.clear(new_x_size, new_y_size, _num_channels);
if (new_x_size < _x_size && new_y_size < _y_size) {
// If we're downscaling, we can use quick_filter, which is faster.
result.quick_filter_from(*this);
if (pfm_resize_gaussian) {
result.gaussian_filter_from(pfm_resize_radius, *this);
} else {
// Otherwise, we should use box_filter(), which is more general.
result.box_filter_from(0.5, *this);
if (new_x_size <= _x_size && new_y_size <= _y_size) {
// If we're downscaling, we can use quick_filter, which is faster.
result.quick_filter_from(*this);
} else {
// Otherwise, we should use box_filter(), which is more general.
result.box_filter_from(pfm_resize_radius, *this);
}
}
_table.swap(result._table);

View File

@ -53,9 +53,9 @@ FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
double filter_width;
make_filter(scale, width, filter, filter_width);
memset(temp_source_weight, 0, source.ASIZE() * sizeof(StoreType));
for (b = 0; b < source.BSIZE(); b++) {
memset(temp_source_weight, 0, source.ASIZE() * sizeof(StoreType));
for (a = 0; a < source.ASIZE(); a++) {
if (source.HASVAL(a, b)) {
temp_source[a] = (StoreType)(source_max * source.GETVAL(a, b, channel));