fix array overrun in PfmFile.resize()
This commit is contained in:
parent
a019520dbc
commit
210780f021
|
|
@ -43,8 +43,9 @@ FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
|
|||
|
||||
WorkType *filter;
|
||||
float filter_width;
|
||||
int actual_width;
|
||||
|
||||
make_filter(scale, width, filter, filter_width);
|
||||
make_filter(scale, width, filter, filter_width, actual_width);
|
||||
|
||||
for (b = 0; b < source.BSIZE(); b++) {
|
||||
for (a = 0; a < source.ASIZE(); a++) {
|
||||
|
|
@ -54,7 +55,7 @@ FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
|
|||
filter_row(temp_dest, dest.ASIZE(),
|
||||
temp_source, source.ASIZE(),
|
||||
scale,
|
||||
filter, filter_width);
|
||||
filter, filter_width, actual_width);
|
||||
|
||||
for (a = 0; a < dest.ASIZE(); a++) {
|
||||
matrix[a][b] = temp_dest[a];
|
||||
|
|
@ -69,13 +70,13 @@ FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
|
|||
scale = (float)dest.BSIZE() / (float)source.BSIZE();
|
||||
temp_dest = (StoreType *)PANDA_MALLOC_ARRAY(dest.BSIZE() * sizeof(StoreType));
|
||||
|
||||
make_filter(scale, width, filter, filter_width);
|
||||
make_filter(scale, width, filter, filter_width, actual_width);
|
||||
|
||||
for (a = 0; a < dest.ASIZE(); a++) {
|
||||
filter_row(temp_dest, dest.BSIZE(),
|
||||
matrix[a], source.BSIZE(),
|
||||
scale,
|
||||
filter, filter_width);
|
||||
filter, filter_width, actual_width);
|
||||
|
||||
for (b = 0; b < dest.BSIZE(); b++) {
|
||||
dest.SETVAL(a, b, channel, (float)temp_dest[b]/(float)source_max);
|
||||
|
|
|
|||
|
|
@ -49,10 +49,12 @@ FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
|
|||
|
||||
WorkType *filter;
|
||||
float filter_width;
|
||||
int actual_width;
|
||||
|
||||
make_filter(scale, width, filter, filter_width);
|
||||
make_filter(scale, width, filter, filter_width, actual_width);
|
||||
|
||||
for (b = 0; b < source.BSIZE(); b++) {
|
||||
memset(temp_source, 0, source.ASIZE() * sizeof(StoreType));
|
||||
memset(temp_source_weight, 0, source.ASIZE() * sizeof(StoreType));
|
||||
for (a = 0; a < source.ASIZE(); a++) {
|
||||
if (source.HASVAL(a, b)) {
|
||||
|
|
@ -64,9 +66,10 @@ FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
|
|||
filter_sparse_row(temp_dest, temp_dest_weight, dest.ASIZE(),
|
||||
temp_source, temp_source_weight, source.ASIZE(),
|
||||
scale,
|
||||
filter, filter_width);
|
||||
filter, filter_width, actual_width);
|
||||
|
||||
for (a = 0; a < dest.ASIZE(); a++) {
|
||||
nassertv(!isnan(temp_dest[a]) && !isnan(temp_dest_weight[a]));
|
||||
matrix[a][b] = temp_dest[a];
|
||||
matrix_weight[a][b] = temp_dest_weight[a];
|
||||
}
|
||||
|
|
@ -83,17 +86,19 @@ FUNCTION_NAME(IMAGETYPE &dest, const IMAGETYPE &source,
|
|||
temp_dest = (StoreType *)PANDA_MALLOC_ARRAY(dest.BSIZE() * sizeof(StoreType));
|
||||
temp_dest_weight = (StoreType *)PANDA_MALLOC_ARRAY(dest.BSIZE() * sizeof(StoreType));
|
||||
|
||||
make_filter(scale, width, filter, filter_width);
|
||||
make_filter(scale, width, filter, filter_width, actual_width);
|
||||
|
||||
for (a = 0; a < dest.ASIZE(); a++) {
|
||||
filter_sparse_row(temp_dest, temp_dest_weight, dest.BSIZE(),
|
||||
matrix[a], matrix_weight[a], source.BSIZE(),
|
||||
scale,
|
||||
filter, filter_width);
|
||||
filter, filter_width, actual_width);
|
||||
|
||||
for (b = 0; b < dest.BSIZE(); b++) {
|
||||
nassertv(!isnan(temp_dest[b]) && !isnan(temp_dest_weight[b]));
|
||||
if (temp_dest_weight[b] != 0) {
|
||||
dest.SETVAL(a, b, channel, (float)temp_dest[b]/(float)source_max);
|
||||
dest.SETVAL(a, b, channel, (float)temp_dest[b]/(float)temp_dest_weight[b]);
|
||||
nassertv(!isnan(dest.GETVAL(a, b, channel)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ filter_row(StoreType dest[], int dest_len,
|
|||
const StoreType source[], int source_len,
|
||||
float scale, // == dest_len / source_len
|
||||
const WorkType filter[],
|
||||
float filter_width) {
|
||||
float filter_width,
|
||||
int actual_width) {
|
||||
// If we are expanding the row (scale > 1.0), we need to look at a
|
||||
// fractional granularity. Hence, we scale our filter index by scale. If
|
||||
// we are compressing (scale < 1.0), we don't need to fiddle with the filter
|
||||
|
|
@ -147,13 +148,15 @@ filter_row(StoreType dest[], int dest_len,
|
|||
// of center--so we don't have to incur the overhead of calling fabs()
|
||||
// each time through the loop.
|
||||
for (source_x = left; source_x < right_center; source_x++) {
|
||||
index = (int)(iscale * (center - source_x) + 0.5f);
|
||||
index = (int)cfloor(iscale * (center - source_x) + 0.5f);
|
||||
nassertv(index >= 0 && index < actual_width);
|
||||
net_value += filter[index] * source[source_x];
|
||||
net_weight += filter[index];
|
||||
}
|
||||
|
||||
for (; source_x <= right; source_x++) {
|
||||
index = (int)(iscale * (source_x - center) + 0.5f);
|
||||
index = (int)cfloor(iscale * (source_x - center) + 0.5f);
|
||||
nassertv(index >= 0 && index < actual_width);
|
||||
net_value += filter[index] * source[source_x];
|
||||
net_weight += filter[index];
|
||||
}
|
||||
|
|
@ -174,15 +177,16 @@ filter_sparse_row(StoreType dest[], StoreType dest_weight[], int dest_len,
|
|||
const StoreType source[], const StoreType source_weight[], int source_len,
|
||||
float scale, // == dest_len / source_len
|
||||
const WorkType filter[],
|
||||
float filter_width) {
|
||||
float filter_width,
|
||||
int actual_width) {
|
||||
// If we are expanding the row (scale > 1.0), we need to look at a
|
||||
// fractional granularity. Hence, we scale our filter index by scale. If
|
||||
// we are compressing (scale < 1.0), we don't need to fiddle with the filter
|
||||
// index, so we leave it at one.
|
||||
|
||||
float iscale;
|
||||
if (scale < 1.0) {
|
||||
iscale = 1.0;
|
||||
if (scale < 1.0f) {
|
||||
iscale = 1.0f;
|
||||
filter_width /= scale;
|
||||
} else {
|
||||
iscale = scale;
|
||||
|
|
@ -211,13 +215,15 @@ filter_sparse_row(StoreType dest[], StoreType dest_weight[], int dest_len,
|
|||
// of center--so we don't have to incur the overhead of calling fabs()
|
||||
// each time through the loop.
|
||||
for (source_x = left; source_x < right_center; source_x++) {
|
||||
index = (int)(iscale * (center - source_x) + 0.5f);
|
||||
index = (int)cfloor(iscale * (center - source_x) + 0.5f);
|
||||
nassertv(index >= 0 && index < actual_width);
|
||||
net_value += filter[index] * source[source_x] * source_weight[source_x];
|
||||
net_weight += filter[index] * source_weight[source_x];
|
||||
}
|
||||
|
||||
for (; source_x <= right; source_x++) {
|
||||
index = (int)(iscale * (source_x - center) + 0.5f);
|
||||
index = (int)cfloor(iscale * (source_x - center) + 0.5f);
|
||||
nassertv(index >= 0 && index < actual_width);
|
||||
net_value += filter[index] * source[source_x] * source_weight[source_x];
|
||||
net_weight += filter[index] * source_weight[source_x];
|
||||
}
|
||||
|
|
@ -244,11 +250,12 @@ filter_sparse_row(StoreType dest[], StoreType dest_weight[], int dest_len,
|
|||
// corresponding to values in the range -filter_width to filter_width.
|
||||
|
||||
typedef void FilterFunction(float scale, float width,
|
||||
WorkType *&filter, float &filter_width);
|
||||
WorkType *&filter, float &filter_width, int &actual_width);
|
||||
|
||||
static void
|
||||
box_filter_impl(float scale, float width,
|
||||
WorkType *&filter, float &filter_width) {
|
||||
WorkType *&filter, float &filter_width,
|
||||
int &actual_width) {
|
||||
float fscale;
|
||||
if (scale < 1.0) {
|
||||
// If we are compressing the image, we want to expand the range of the
|
||||
|
|
@ -263,7 +270,11 @@ box_filter_impl(float scale, float width,
|
|||
fscale = scale;
|
||||
}
|
||||
filter_width = width;
|
||||
int actual_width = (int)cceil((filter_width + 1) * fscale) + 1;
|
||||
|
||||
// It seems we need a buffer of two extra values in the filter array
|
||||
// to allow room for all calculations (especially including the 1/2
|
||||
// pixel offset).
|
||||
actual_width = (int)cceil((filter_width + 1) * fscale) + 2;
|
||||
|
||||
filter = (WorkType *)PANDA_MALLOC_ARRAY(actual_width * sizeof(WorkType));
|
||||
|
||||
|
|
@ -274,7 +285,8 @@ box_filter_impl(float scale, float width,
|
|||
|
||||
static void
|
||||
gaussian_filter_impl(float scale, float width,
|
||||
WorkType *&filter, float &filter_width) {
|
||||
WorkType *&filter, float &filter_width,
|
||||
int &actual_width) {
|
||||
float fscale;
|
||||
if (scale < 1.0) {
|
||||
// If we are compressing the image, we want to expand the range of the
|
||||
|
|
@ -291,7 +303,11 @@ gaussian_filter_impl(float scale, float width,
|
|||
|
||||
float sigma = width/2;
|
||||
filter_width = 3.0 * sigma;
|
||||
int actual_width = (int)cceil((filter_width + 1) * fscale);
|
||||
|
||||
// It seems we need a buffer of two extra values in the filter array
|
||||
// to allow room for all calculations (especially including the 1/2
|
||||
// pixel offset).
|
||||
actual_width = (int)cceil((filter_width + 1) * fscale) + 2;
|
||||
|
||||
// G(x, y) = (1(2 pi sigma^2)) * exp( - (x^2 + y^2) (2 sigma^2))
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue