RFC 15:带屏蔽
作者:弗兰克·温特丹
联系方式:warmerdam@pobox.com
状态:通过
总结
一些文件格式支持位掩码的概念来标识无效数据的像素。这对于字节图像格式尤其有价值,因为所有像素值都具有有效的含义,因此无法使用nodata像素值。这个RFC试图通过GDAL API形式化一种识别和访问此类空掩码的方法,同时转移到表示其他类型掩码(nodata值和alpha带)的统一方法。
基本方法是将这些遮罩视为栅格带,而不是数据源上的常规栅格带。相反,它们是独立的栅格标注栏,其方式与概述栅格标注栏对象类似。掩码表示为GDT_字节带,值为零表示nodata,非零值表示有效数据。通常,值255将用于有效的数据像素。
API
GDALRasterBand通过以下方法进行扩展:
virtual GDALRasterBand *GetMaskBand();
virtual int GetMaskFlags();
virtual CPLErr CreateMaskBand( int nFlags );
GDALDataset使用以下方法进行扩展:
virtual CPLErr CreateMaskBand( nFlags );
请注意,GetMaskBand()应该始终返回一个gdalStartBand掩码,即使它只是一个all 255掩码,其标志指示GMF_all_VALID。
GetMaskFlags()方法返回一组按位或按ed排列的状态标志,这些状态标志具有以下可用定义,将来可能会扩展这些定义:
GMF_ALL_VALID(0x01):没有无效像素,所有掩码值将为255。使用时,这通常是唯一的标志集。
GMF_PER_数据集(0x02):在数据集上的所有带区之间共享掩码带区。
GMF_ALPHA(0x04):遮罩频带实际上是一个ALPHA频带,其值可能不是0和255。
GMF_NODATA(0x08):表示掩码实际上是从NODATA值生成的。(GMF_ALPHA互斥)
CreateMaskBand()方法将尝试创建与调用它的带区关联的掩码带区,如果不支持,则发出错误消息。当前,在创建掩码带区时唯一有意义的标志是GMF_PER_DATASET。其余用于表示特殊系统提供的掩模带。当对数据集调用CreateMaskBand()时,假定为GMF_PER_数据集。
默认的GetMaskBand()/GetMaskFlags()实现
gdalStartBand类将包含GetMaskBand()的默认实现,该实现返回三个默认实现之一。
如果存在对应的.msk文件,则它将用于掩码带区。
如果band设置了nodata值,则将返回新GDALNodataMaskRasterBand类的实例。GetMaskFlags()将返回GMF_NODATA。
如果没有nodata值,但数据集有一个alpha带,似乎应用于此带(具体规则尚待确定),并且是GDT_Byte类型,则将返回该alpha带,并在标志中返回GMF_PER_dataset和GMF_alpha标志。
如果上述两个都不适用,则将返回一个新gdalallvalidasterband类的实例,该实例对所有像素都有255个值。空标志将返回GMF_ALL_VALID。
GDALRasterBand将包含一个受保护的poMask实例变量和一个bOwnMask标志。对默认GetMaskBand()的第一次调用将创建GDALNodataMaskRasterBand、GDALAllValidMaskRasterBand,并在bOwnMask设置为TRUE时将它们分配给poMask。如果一个alpha波段被识别为要使用,它将被分配给poMask,并将bOwnMask设置为FALSE。如果在析构函数中set和bOwnMask为true,GDALRasterBand类将负责删除poMask。只要保持语义,派生的band类就可以安全地使用poMask和bOwnMask标志。
对于要由GDAL识别的外部.msk文件,它必须是有效的GDAL数据集,与主数据集同名,并以.msk作为后缀,可以是一个带区(在GMF_PER_数据集的情况下),也可以是与主数据集一样多的带区。它必须在数据集级别设置内部掩码标志xx元数据项,其中xx与主数据集的带区编号匹配。这些项的值是标志GMF_ALL_VALID、GMF_PER_DATASET、GMF_ALPHA和GMF_NODATA的组合。如果某个标注栏缺少元数据项,则将使用上面解释的其他规则生成即时掩码标注栏。
默认CreateMaskBand()
CreateMaskBand()方法的默认实现将基于与使用GDALDefaultOverviews对象实现的.ovr处理相似的规则来实现。将创建一个扩展名为.msk的TIFF文件,该文件的基名称与原始文件的基名称相同,并且它将具有与原始图像相同的条带(或者对于GMF_PER_数据集仅具有一个条带)。如果可能的话,掩模图像将以与原始图像相同的块大小压缩平铺图像。
GetFileList()的默认实现也将被修改以了解.msk文件。
创建副本()
如果有必要和可能,将更新GDALDriver::DefaultCreateCopy()和GDALPamDataset::CloneInfo()方法以复制掩码信息。请注意,NODATA、所有有效掩码和ALPHA类型掩码都不会被复制,因为它们只是派生信息。
阿尔法带
当一个数据集有一个正常的GDT_Byte alpha(透明)频带时,它应该作为空掩码返回,但是GetMaskFlags()方法应该包括GMF_alpha。出于处理目的,除了0以外的任何值都应视为有效数据,尽管某些算法将1到254之间的值视为部分透明。
驱动程序已更新
这些驱动程序将更新:
JPEG驱动程序:支持一些数据提供程序使用的“附加到文件的zlib压缩掩码”方法。
GRASS驱动程序:更新以支持将空值作为掩码处理。
可能更新:
HDF4驱动程序:如果我们能找到一个方法,这个驱动程序可能会被更新以返回真正的掩码。
SDE驱动程序:如果霍华德有足够的时间和热情,这个驱动程序可能会更新。
公用事业
gdalwarp实用程序和gdal warper算法将更新为在输入时使用空掩码。warper算法实际上已经在内部使用了这个模型。目前,gdalwarp输出(nodata或alpha band)将保持不变,不过在将来的某个时候,可能会添加显式生成空掩码的支持,但在大多数情况下,生成alpha band就是生成空掩码。
实施计划
这个更改将由Frank wartemdam在trunk中为1.5.0版本及时实现。
SWIG含义
需要添加GetMaskBand()、GetMaskFlags()和CreateMaskBand()方法(以及相应的定义)。为了swig的目的,遮罩应该像普通的栅格带一样工作,所以需要最少的特殊工作。
测试
gdalautotest将扩展如下:
gcore/mask.py:测试nodata、alpha和所有有效案例的默认掩码实现。
gdriver/jpeg.py:使用“附加位掩码”大小写创建和读取测试进行扩展。
将对gdalwarp进行交互式测试。