Summary
write_vrt builds the GDAL dataType attribute for the output VRT by reconstructing a dtype name from sample_format and bps directly, instead of going through the central resolver in _dtypes.py. The local ladder has no entry for bps=12, so unsigned 12-bit TIFF sources are tagged as Byte in the VRT header. Downstream GDAL/VRT readers can then truncate sample values above 255.
Location
- Duplicate dtype logic:
xrspatial/geotiff/_vrt.py lines 1507-1519
- Correct resolver:
xrspatial/geotiff/_dtypes.py, tiff_dtype_to_numpy (handles bps=12 -> uint16 at line 105)
Current code
sf = first['sample_format']
bps = first['bps']
if sf == 3:
vrt_dtype_name = 'Float64' if bps == 64 else 'Float32'
elif sf == 2:
vrt_dtype_name = {8: 'Int8', 16: 'Int16', 32: 'Int32', 64: 'Int64'}.get(bps, 'Int32')
else:
vrt_dtype_name = {8: 'Byte', 16: 'UInt16', 32: 'UInt32', 64: 'UInt64'}.get(bps, 'Byte')
For bps=12, sf=1 this falls through to 'Byte'. The reader path promotes the same source to uint16 (_dtypes.py:105), so the VRT advertises a narrower type than the actual decoded data.
The local fallback defaults ('Int32' for unknown signed, 'Byte' for unknown unsigned) also silently mis-type any future bit width that lands here.
Fix direction
Route VRT dtype through tiff_dtype_to_numpy(bps, sample_format) and map the numpy dtype to a GDAL name via the existing _NP_TO_VRT_DTYPE table at _vrt.py:1337. Raise ValueError if the resolved numpy dtype has no GDAL name, instead of defaulting to Byte.
Repro
A VRT built from a 12-bit unsigned source TIFF gets dataType="Byte" in <VRTRasterBand> despite the source decoding as uint16.
Summary
write_vrtbuilds the GDALdataTypeattribute for the output VRT by reconstructing a dtype name fromsample_formatandbpsdirectly, instead of going through the central resolver in_dtypes.py. The local ladder has no entry forbps=12, so unsigned 12-bit TIFF sources are tagged asBytein the VRT header. Downstream GDAL/VRT readers can then truncate sample values above 255.Location
xrspatial/geotiff/_vrt.pylines 1507-1519xrspatial/geotiff/_dtypes.py,tiff_dtype_to_numpy(handlesbps=12->uint16at line 105)Current code
For
bps=12, sf=1this falls through to'Byte'. The reader path promotes the same source touint16(_dtypes.py:105), so the VRT advertises a narrower type than the actual decoded data.The local fallback defaults (
'Int32'for unknown signed,'Byte'for unknown unsigned) also silently mis-type any future bit width that lands here.Fix direction
Route VRT dtype through
tiff_dtype_to_numpy(bps, sample_format)and map the numpy dtype to a GDAL name via the existing_NP_TO_VRT_DTYPEtable at_vrt.py:1337. RaiseValueErrorif the resolved numpy dtype has no GDAL name, instead of defaulting toByte.Repro
A VRT built from a 12-bit unsigned source TIFF gets
dataType="Byte"in<VRTRasterBand>despite the source decoding asuint16.