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进行交互式测试。