Hello G.E. -

I agree* with your conclusion that the constant in the scale

factor should be 255. I give my reasoning below.

To make the analysis simpler and more extreme, let’s consider

converting a 32-bit floating-point image to a 2-bit image whose

pixels take on the values (0, 1, 2, 3). For simplicity, let the

pixel values in the floating point image run from [0.0, 1.0].

(This is irrelevant to the analysis – the minimum and maximum

values drop out of the calculation.)

Here is the relevant code from FloatProcessor.java:

```
double value;
int ivalue;
double min2 = getMin(), max2=getMax();
int maxValue = 255;
double scale = 256.0/(max2-min2);
// if (thresholding) {
// maxValue = 254;
// scale = 255.0/(max2-min2);
// }
for (int i=0; i<size; i++) {
value = pixels[i]-min2;
if (value<0.0) value=0.0;
ivalue = (int)((value*scale)+0.5f);
if (ivalue>maxValue) ivalue = maxValue;
pixels8[i] = (byte)ivalue;
}
```

I’ve commented out the `if (thresholding) {}`

part to avoid

confusion.

For our 2-bit case, `scale == 4.0`

(and `maxValue == 3`

), and

```
ivalue = (int) ( (4.0 * value) + 0.5 );
```

Here is how the (nearly) continuous `value`

maps to the discrete

`ivalue`

, and the fraction, `f`

, of `[0, 1]`

that maps to each `ivalue`

:

```
[0, 1/8) --> 0; f = 1/8
[1/8, 3/8) --> 1; f = 1/4
[3/8, 5/8) --> 2; f = 1/4
[5/8, 1] --> 3; f = 3/8
```

This is asymmetric. There seems to be no good reason that three

times as much of the range `[0, 1]`

maps to `ivalue == 3`

than

maps to `ivalue == 0`

.

Note, it’s equivalent, but it might help the explanation to break

the range `[5/8, 1]`

up into two pieces:

```
[5/8, 7/8) --> 3; f = 1/4
[7/8, 1] --> 3; f = 1/8
```

If, instead, we use G.E.'s suggestion to use (in our example case)

`scale == 3.0`

, we get:

```
[0, 1/6) --> 0; f = 1/6
[1/6, 1/2) --> 1; f = 1/3
[1/2, 5/6) --> 2; f = 1/3
[5/6, 1] --> 3; f = 1/6
```

This is symmetric, and I would say clearly more satisfactory than

the choice of `scale == 4.0`

.

*) However, even using `scale == 3.0`

still seems imperfect;

the two end bins get only half the love that the two central bins

do. This can be remedied by getting rid of the “offset” of `0.5`

(and using the original `scale == 4.0`

). That is, using (for our

2-bit case):

```
ivalue = (int) (4.0 * value);
```

we get:

```
[0, 1/4) --> 0; f = 1/4
[1/4, 1/2) --> 1; f = 1/4
[1/2, 3/4) --> 2; f = 1/4
[3/4, 1) --> 3; f = 1/4
```

This seems better still.

Thanks, mm