@@ -364,17 +364,25 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
364364
365365 # TODO slice input array first
366366 inp_dtype = A .dtype
367- if inp_dtype .kind == 'f' :
368- scaled_dtype = A .dtype
369- else :
370- scaled_dtype = np .float32
371-
372367 a_min = A .min ()
368+ a_max = A .max ()
369+ # figure out the type we should scale to. For floats,
370+ # leave as is. For integers cast to an appropriate-sized
371+ # float. Small integers get smaller floats in an attempt
372+ # to keep the memory footprint reasonable.
373373 if a_min is np .ma .masked :
374- a_min , a_max = 0 , 1 # all masked, so values don't matter
374+ # all masked, so values don't matter
375+ a_min , a_max = np .int32 (0 ), np .int32 (1 )
376+ if inp_dtype .kind == 'f' :
377+ scaled_dtype = A .dtype
375378 else :
376- a_min = a_min .astype (scaled_dtype )
377- a_max = A .max ().astype (scaled_dtype )
379+ # probably an integer of some type.
380+ da = a_max .astype (np .float64 ) - a_min .astype (np .float64 )
381+ if da > 1e8 :
382+ # give more breathing room if a big dynamic range
383+ scaled_dtype = np .float64
384+ else :
385+ scaled_dtype = np .float32
378386
379387 # scale the input data to [.1, .9]. The Agg
380388 # interpolators clip to [0, 1] internally, use a
@@ -386,6 +394,9 @@ def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
386394 A_scaled = np .empty (A .shape , dtype = scaled_dtype )
387395 A_scaled [:] = A
388396 A_scaled -= a_min
397+ a_min = a_min .astype (scaled_dtype )
398+ a_max = a_max .astype (scaled_dtype )
399+
389400 if a_min != a_max :
390401 A_scaled /= ((a_max - a_min ) / 0.8 )
391402 A_scaled += 0.1
0 commit comments