JP2Grok 驱动:基于 Grok 库的 GDAL JPEG2000 读写实现全解
GIS遥感数据工程【免费下载链接】gdalGDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.项目地址https://gitcode.com/gh_mirrors/gd/gdal点击查看免费下载导读JP2Grok 是 GDAL 3.13 起新增的 JPEG2000 读写驱动其核心是基于开源的 Grok 图像压缩库GrokImageCompression/grok需 Grok 20.2。它借助 VSI 虚拟文件 API 读取 JPEG2000 压缩的 NITF 文件并利用 Grok 内置的云 I/O 支持原生 S3 访问写入端则支持 GeoJP2 / GMLJP2 地理参考框、任意波段数、透明通道与元数据以及仅需重写 JP2 框而不重新编解码的 TRANSCODE 模式。读完本文你将掌握该驱动的读取架构异步解压 AdviseRead 性能优化、全部 Open/Creation 选项的语义与取值以及从有损到无损压缩、INSPIRE 合规输出、独立插件编译的完整实战配置。驱动概览与能力JP2Grok 由 frmts/grok/grokdataset.cpp 实现。从 注册代码 可以看到它复用共享模板jp2opjlikedataset.cpp提供的 Open / CreateCopy / Identify 流程再通过两个组件注入 Grok 专属行为GRKCodecWrapper封装 Grok 编解码器grk_object*、图像与压缩/解压参数JP2GRKDatasetBase基于 DirectRasterIO 的读取与异步解压实现。驱动元数据见 jp2grokdrivercore.cpp显示元数据值长名称JPEG-2000 driver based on Grok library创建数据类型Byte Int16 UInt16 Int32 UInt32扩展名jp2 j2kMIME 类型image/jp2虚拟 I/O支持GDAL_DCAP_VIRTUALIOYES识别机制驱动通过文件头签名识别格式见 Identify 实现J2K 裸码流前 4 字节匹配 SOC RSIZ 标记0xff 0x4f 0xff 0x51JP2 文件偏移 4 处匹配jP0x6a 0x50 0x20 0x20框签名。文件格式支持读取JP2 / J2K 码流经 VSI 虚拟文件系统可读取 JPEG2000 压缩的 NITF 文件/vsis3/路径通过 Grok 原生 libcurl I/O 直读 S3详见下文元数据XMP 元数据可被提取并存放于xml:XMP元数据域xml:IPR知识产权元数据可读写写入GeoJP2GeoTIFF in JPEG2000 UUID 框与 GMLJP2 地理参考框、透明度、任意波段数、元数据以及现有文件的地理参考/元数据更新。读取架构与性能异步解压与 AdviseReadDirectRasterIO 直读路径与 OpenJPEG 驱动的SetDecodeArea ReadBlock不同Grok 驱动的canPerformDirectIO()恒为true见 grkdatasetbase.h所有栅格读取绕过 GDAL 块缓存统一走Band::IRasterIO - Dataset::DirectRasterIO - decompressAsynch - grk_decompress / grk_decompress_wait - CopyTiles - CopyTileData首次读取时decompressAsynch()调用一次grk_decompress()启动整幅图像的异步解码随后复用缓存的 tile-grid 信息为每个请求的 swath 重算瓦片坐标。多线程Grok 库内部通过自己的线程池做多线程解压也支持多线程编码线程数在运行时由GDALGetNumThreads决定。源码中grk_initialize()的线程数取GDALGetNumThreads(GDAL_DEFAULT_MAX_THREAD_COUNT, true)见 grkdatasetbase.h且每个进程仅初始化一次当 JPEG2000 文件包含多个瓦片时GDAL 还会额外把瓦片处理分发到线程池并行执行CopyTileData见多瓦片分支 grkdatasetbase.h。单瓦片时则不做线程池开销。AdviseRead为最佳性能提供读窗口提示驱动会异步解压在调用方仍在消费前几行时后台就调度后续瓦片解码。要做到高效它需要提前知道读窗口从而把码流解码限制在目标 precincts/瓦片上并把 T2 解析与 T1 解码重叠。因此对已知读窗口的调用方应在首次RasterIO/ReadBlock之前用GDALDataset::AdviseRead或 C APIGDALDatasetAdviseRead告知该窗口ds-AdviseRead(nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, eDT, nBandCount, panBandList, nullptr);AdviseRead实现见 grkdatasetbase.h会记录区域坐标、判断是否为整幅读取并重置异步状态以便对新区域发起全新grk_decompress()。没有该提示时驱动会退化为同步、按 swath 解压bSyncFallback_路径见 grkdatasetbase.h速度可能明显变慢——尤其在通过网络解压时。自动化测试中也有专门用例验证这条路径如test_jp2grok_sync_fallback_full_image、test_jp2grok_advise_read_keeps_async_path见 autotest/gdrivers/jp2grok.py。1-bit Alpha 提升当 JP2 的 cdef 框标明 1-bit 精度 alpha 波段时DirectRasterIO会把该 alpha 波段的下标传给CopyTileData将解码出的 0/1 值乘以 255 提升为 8-bit见 grkdatasetbase.h。该行为受开放选项1BIT_ALPHA_PROMOTION控制。地理参考Georeferencing地理参考信息可来自多个来源内部GeoJP2 或 GMLJP2 框、worldfile.j2w/.wld侧车文件、或 PAM.aux.xml持久辅助元数据侧车文件。默认按如下顺序获取先列出者优先级最高PAM, GeoJP2, GMLJP2, WORLDFILE可用GDAL_GEOREF_SOURCES配置项或GEOREF_SOURCES开放选项修改允许的来源与优先级其值是以逗号分隔的关键字列表关键字含义PAMPersistent Auxiliary Metadata.aux.xmlGEOJP2GeoJP2 框GeoTIFF in JPEG2000GMLJP2GMLJP2 框INTERNALGEOJP2,GMLJP2 的快捷方式WORLDFILE.j2w / .wld 侧车文件NONE不使用任何来源排在前面的来源优先于后面的未被提及的来源将被忽略。示例设置WORLDFILE,PAM,INTERNALworldfile 得到的仿射变换矩阵将优先于 PAM 或内部 JP2 框设置PAM,WORLDFILE,GEOJP2只使用所列来源忽略 GMLJP2 框。驱动注册的默认值即PAM,GEOJP2,GMLJP2,WORLDFILE见 grkdatasetbase.h。自动化测试也验证了 PAM 覆盖内部地理参考 的场景见 autotest/gdrivers/jp2grok.py。Open Options打开选项除 通用打开选项 外JP2Grok 支持以下打开选项1BIT_ALPHA_PROMOTION取值YES / NO默认YES1-bit alpha 通道是否提升为 8-bit。提升发生在读取路径见上文CopyTileData的乘法处理。GEOREF_SOURCES自 2.2 起该选项在 JP2 驱动族中通用定义允许的地理参考来源及优先级见上文“地理参考”一节。OPEN_REMOTE_GML取值YES / NO默认NO是否加载 GMLJP2 v2 框中通过链接引用的远程矢量图层该选项未写入 RST但已在驱动元数据中注册见 grkdatasetbase.h。USE_TILE_AS_BLOCK取值YES / NO默认NO是否始终以 JPEG2000 瓦片尺寸作为 GDAL 块尺寸。整幅解压且图像为单瓦片时该选项有用。注意瓦片尺寸不得超过 2 GB——这是 GDAL 支持的极限。Creation Options创建选项CODEC取值JP2 / J2KJP2 会在码流外围添加 JP2 框该值根据文件扩展名自动判定若扩展名既非 JP2 也非 J2K则使用 J2K 编解码。GMLJP2取值YES / NO默认YES是否在文件中加入符合 OGC GML in JPEG2000 规范的 GML 框。除非使用GMLJP2V2_DEF否则 GMLJP2 框版本为 v1。GMLJP2V2_DEF取值YES /filename/json是否加入符合 OGC GML in JPEG2000, version 2.0.1 规范的 GML 框。filename须指向一个 JSON 文件内容定义 GMLJP2 v2 框的构建方式语法见 JP2OpenJPEG 驱动文档也可直接内联传入 JSON 字符串。若 filename 仅设为YES则构建最小实例。GeoJP2取值YES / NO默认YES是否在文件中加入符合 GeoJP2GeoTIFF in JPEG2000规范的 UUID/GeoTIFF 框。QUALITY取值float_value,float_value,...0~100 的百分比含义50 表示文件约为未压缩数据的 1/2 大小33 表示 1/3依此类推。默认 25除非数据集为带颜色表的单波段此时默认质量为 100。可指定多个逗号分隔质量值以生成多个质量层各值应为递增顺序。REVERSIBLE取值YES / NOYES 使用可逆的 5x3 整数滤波器NO 使用不可逆 DWT 9-7。默认 NO除非数据集为带颜色表的单波段此时使用可逆滤波器。源码中irreversible标志直接映射到compressParams.irreversible见 grkdatasetbase.h。RESOLUTIONS取值integer注册范围 1~30分辨率级数。默认值取为使瓦片最小概览不超过 128x128。BLOCKXSIZE / BLOCKYSIZE取值integer默认1024瓦片宽 / 瓦片高。映射到compressParams.t_width/t_height。PROGRESSION取值LRCP / RLCP / RPCL / PCRL / CPRL默认LRCP渐进顺序Layer-Resolution-Component-Position 的五种排列。SOP / EPH取值YES / NO默认NOSOPStart Of Packet包起始标记段/ EPHEnd of Packet Header包头结束标记段标记段是否生成。源码中分别置compressParams.csty | 0x02/0x04见 grkdatasetbase.h。YCBCR420取值YES / NO默认NORGB 是否重采样为 YCbCr 4:2:0Cb/Cr 分量以 dxdy2 半分辨率交错存储见 grkdatasetbase.h 的缓冲布局注释。YCC取值YES / NO默认YESRGB 是否变换到 YCC 色彩空间“MCT 变换”即内部变换、无视觉损伤。映射到compressParams.mct。NBITS取值integer亚字节文件1-7、亚 uint169-15、亚 uint3217-31的位深精度。1BIT_ALPHA取值YES / NO有 alpha 通道时是否将其编码为 1-bit 通道。默认 NO除非INSPIRE_TGYES。启用该选项可能在某些读取器中引起兼容性问题。ALPHA取值YES / NO默认NO是否强制把最后一个通道编码为 alpha 通道。仅在该通道的色彩解释本身不是 Alpha 时才有用。PROFILE取值AUTO / UNRESTRICTED / PROFILE_1默认AUTO决定码流使用的 profileUNRESTRICTED对应 Unrestricted JPEG 2000 Part 1 codestreamRSIZ0PROFILE_1对应 JPEG 2000 Part 1 Profile 1 codestreamRSIZ2它对瓦片尺寸与分辨率级数增加约束。AUTO 模式下驱动会判断BLOCKXSIZE、BLOCKYSIZE、RESOLUTIONS、CODEBLOCK_WIDTH、CODEBLOCK_HEIGHT是否与 PROFILE_1 兼容并据此声明上述选项的默认值均与 PROFILE_1 兼容。PROFILE_1在源码中映射为compressParams.rsiz GRK_PROFILE_1见 grkdatasetbase.h。INSPIRE_TG取值YES / NO默认NO是否使用符合 Inspire Orthoimagery Technical Guidelines 的 JPEG2000 特性。设为 YES 时隐式启用PROFILEPROFILE_1、1BIT_ALPHAYES、GEOBOXES_AFTER_JP2CYES并会对CODEC、BLOCKXSIZE、BLOCKYSIZE、RESOLUTIONS、NBITS、PROFILE、CODEBLOCK_WIDTH、CODEBLOCK_HEIGHT逐一检查是否符合该指南的要求与建议检查逻辑见 grkdatasetbase.h。JPX取值YES / NO默认YES写入 GMLJP2 框时是否声明 JPX 特性并添加 Reader requirement 框。除非与某个读取器出现兼容性问题否则不应改动该选项。GEOBOXES_AFTER_JP2C取值YES / NO是否把 GeoJP2/GMLJP2 框放在码流之后。默认 NO除非INSPIRE_TGYES。同样除非兼容性问题否则不应改动。PRECINCTS取值{prec_w,prec_h},{prec_w,prec_h},...precincts 尺寸的 {宽,高} 元组列表。每个值须为 2 的倍数使用的元组数最多为分辨率级数第一个元组对应最高分辨率层其后依次对应更低层。若元组数不足最后一组的值会在每个更低分辨率层上除以 2。默认{512,512},{256,512},{128,512},{64,512},{32,512},{16,512},{8,512},{4,512},{2,512}。空字符串可用来禁用 precincts此时使用默认的{32767,32767},{32767,32767},...。解析逻辑见 grkdatasetbase.h启用 precincts 时置compressParams.csty | 0x01。TILEPARTS取值DISABLED / RESOLUTIONS / LAYERS / COMPONENTS默认DISABLED是否生成 tile-parts 以及按何种标准划分RESOLUTIONS/LAYERS/COMPONENTS 分别把新 tile-part 的渐进分隔符设为 R/L/C见 grkdatasetbase.h。LAYERS 在单层码流时没有实际意义源码会给出警告。CODEBLOCK_WIDTH / CODEBLOCK_HEIGHT取值integer默认64码块宽/高4~1024 之间的 2 的幂。注意CODEBLOCK_WIDTH * CODEBLOCK_HEIGHT不得大于 4096。为兼容 PROFILE_1二者均不得大于 64。CODEBLOCK_STYLE码块编码通道coding pass的风格。以下 6 个独立设置可组合值用逗号分隔名称数值含义BYPASS1启用选择性算术编码旁路可显著提升编解码速度代价是文件更大RESET2在编码通道边界重置上下文概率TERMALL4在每个编码通道上启用终止VSC8启用垂直因果上下文PREDICTABLE16启用可预测终止利于错误检测SEGSYM32启用分段符号利于错误检测除按文本指定外也可直接给出全局码块风格对应的数值把所选选项相加例如BYPASS,TERMALL等价于514。默认全部不启用启用它们通常会增大码流但会改善编解码速度或鲁棒性/错误检测。源码同时支持文本词与 0~63 的整数值grkdatasetbase.h。PLT / TLM取值YES / NO默认NOPLTPacket Length标记段写入 tile-part 头TLMTile-part Length标记段写入主头。源码映射为compressParams.write_plt/write_tlmgrkdatasetbase.h。WRITE_METADATA取值YES / NO默认NO是否把元数据写入专门的 JP2 xml 框。xml 框内容形如GDALMultiDomainMetadata Metadata MDI keyfoobar/MDI /Metadata Metadata domainaux_domain MDI keyfoobar/MDI /Metadata Metadata domaina_xml_domain formatxml arbitrary_xml_content /arbitrary_xml_content /Metadata /GDALMultiDomainMetadata名称以xml:BOX_开头的元数据域各自写入独立的 JP2 xml 框名为xml:XMP的元数据域写入 JP2 uuid XMP 框名为xml:IPR的元数据域写入 JP2 jp2i 框。MAIN_MD_DOMAIN_ONLY取值YES / NO默认NO仅在WRITE_METADATAYES时有效是否只写入主元数据域的元数据。USE_SRC_CODESTREAM实验性取值YES / NO当源数据集是 JPEG2000 时是否原样复用源数据集的码流。默认 NO。注意启用该特性可能导致 JP2 框内容与源码流内容不一致此模式下大多数其他创建选项被忽略。在只增改地理参考、元数据等场景可能有用。TRANSCODE取值YES / NO默认NO当源数据集是 JPEG2000 时不经过完整的解压/重压缩往返直接转码码流底层码流数据原样复制同时可用以下选项修改标记段或渐进顺序PLT插入 PLTPacket Length, Tile-part标记段TLM插入 TLMTile-part Length标记段SOP插入 SOPStart Of Packet标记段EPH插入 EPHEnd of Packet Header标记段PROGRESSION改变渐进顺序LRCP / RLCP / RPCL / PCRL / CPRLJP2 元数据框GeoTIFF UUID、XMP、GMLJP2、IPR、GDAL xml从当前数据集元数据重新生成。因为码流系数是复制而非重新编码会影响像素数据的创建选项——QUALITY、REVERSIBLE、BLOCKXSIZE、BLOCKYSIZE、RESOLUTIONS、YCBCR420、YCC、NBITS、1BIT_ALPHA、PRECINCTS、TILEPARTS、CODEBLOCK_WIDTH、CODEBLOCK_HEIGHT、CODEBLOCK_STYLE、USE_SRC_CODESTREAM——都会被忽略若提供了其中任一选项会发出警告忽略清单见 grkdatasetbase.h。示例gdal_translate -of JP2Grok -co TRANSCODEYES \ -co PLTYES -co TLMYES -co PROGRESSIONRPCL \ input.jp2 output.jp2自动化测试如test_jp2grok_transcode_markers、test_jp2grok_transcode_ignored_options验证了转码后像素数据与地理参考保持不变、以及忽略选项告警行为见 autotest/gdrivers/jp2grok.py。COMMENT取值string码流中注释COM标记的内容。源码中经compressParams.num_comments/comment/comment_len传递grkdatasetbase.h。未指定时驱动会写入 Created by Grok version x.y.z 并附上 LOSSLESS/LOSSY 设置说明。其他注册选项驱动元数据中还注册了CT_COMPONENTS颜色表分量数3~4自动探测见 grkdatasetbase.h。无损压缩Lossless Compression当同时满足以下全部创建选项时可实现无损压缩QUALITY100REVERSIBLEYESYCBCR420NO这是默认值从源码看真正无损可逆小波 QUALITY100 对应的 rate 1.0 且非 YCBCR420时驱动会把numlayers置 1、layer_rate[0]置 0 并关闭 rate-distortion 分配令 Grok 保留全部数据grkdatasetbase.h。自动化测试test_jp2grok_lossless_byteautotest/gdrivers/jp2grok.py即验证了无损路径且读取端可通过IMAGE_STRUCTURE域的COMPRESSION_REVERSIBILITY元数据判断文件为 LOSSLESS 还是 LOSSY见 autotest/gdrivers/jp2grok.py。实例常用创建命令将普通栅格转成有损 JPEG2000gdal_translate -of JP2Grok input.tif output.jp2 \ -co QUALITY50 -co REVERSIBLENO \ -co BLOCKXSIZE512 -co BLOCKYSIZE512 -co PROGRESSIONLRCP无损压缩调色板/单波段色表图像默认即为无损此处强制gdal_translate -of JP2Grok input.tif output.jp2 \ -co QUALITY100 -co REVERSIBLEYESINSPIRE 正射影像合规输出gdal_translate -of JP2Grok input.tif output.jp2 \ -co INSPIRE_TGYES读取时指定地理参考来源优先级gdal_translate -oo GEOREF_SOURCESWORLDFILE,PAM,INTERNAL -of GTiff input.jp2 output.tif云与虚拟文件系统支持驱动通过 VSI 虚拟文件 API 读取 JPEG2000 压缩的 NITF 文件。在HAVE_CURL且 Grok 具备GRK_HAS_LIBCURL的构建下/vsis3/路径会走 Grok 原生 S3 I/OGDAL 通过VSIS3HandleHelper解析完整 AWS 认证链AccessKeyId / SecretAccessKey / SessionToken / Region / Endpoint并把凭据经grk_stream_paramsusername/password/bearer_token/region/s3_endpoint 等字段传给 Grok由其用 libcurl 直接拉取 S3 数据见 grkdatasetbase.h。其他/vsi*虚拟路径则退回 VSILFILE 回调读/写/寻址回调见 grkdatasetbase.h本地普通文件由 Grok 原生文件 I/O 直读GrokCanRead()判定逻辑见 grkdatasetbase.h。另外GRK_DEBUG环境变量控制 Grok 消息回调的详细级别0静默、1仅错误、2错误警告、3错误警告信息、4全部含调试未设置时默认错误警告信息grkdatasetbase.h。独立插件编译Standalone pluginJP2Grok 既可随 libgdal 整体构建内置或插件也可仅把该驱动作为插件、针对已构建好的 libgdal 单独编译。前提编译驱动所用的 GDAL 源码版本必须与所针对的 libgdal 版本一致。例如在 GDAL 源码树根下的build_grok目录中执行cmake -S ../frmts/grok -DCMAKE_PREFIX_PATH/path/to/GDAL_installation_prefix -DGROK_ROOT/path/to/grok_install_prefix cmake --build .构建脚本逻辑见 frmts/grok/CMakeLists.txt未处于整体构建时启用SetupStandalonePlugin.cmake与CheckDependentLibrariesGrok目标gdal_JP2Grok链接GROK::grokj2k并在GDAL_USE_CURL时定义HAVE_CURL。驱动的注册入口GDALRegister_JP2Grok()位于 grokdataset.cpp。注意这种插件在用于不感知它的 libgdal 时会在 GDAL 驱动初始化时被系统性加载无法享受延迟插件加载能力。要启用延迟加载libgdal 本身必须以 CMake 变量GDAL_REGISTER_DRIVER_JP2GROK_FOR_LATER_PLUGINON构建。延迟插件声明逻辑见 jp2grokdrivercore.cppDeclareDeferredJP2GrokPlugin。常见问题与调试网络解压慢未调用AdviseRead时会回退到同步逐 swath 解压网络场景尤其明显。调用方应尽量在首次读取前给出读窗口提示。块尺寸超过限制USE_TILE_AS_BLOCKYES时瓦片尺寸不得超过 2 GB。PROFILE_1 约束码块宽高均须 ≤ 64 且面积 ≤ 4096瓦片尺寸与分辨率级数有额外约束不满足时请使用PROFILEUNRESTRICTED。TRANSCODE 下的无效选项影响像素数据的选项会被静默忽略附警告确认输出前检查告警信息。调试日志设置GRK_DEBUG4可查看瓦片网格、分辨率数、分量精度等解码细节驱动内部消息以 GROK 前缀输出。关联驱动与其他资源JP2Grok 是 GDAL 的 JPEG2000 驱动家族之一其他成员包括JP2OpenJPEG基于 OpenJPEG 库开源JP2ECW基于 Erdas ECW 库专有JP2MRSID基于 LizardTech MrSID 库专有JP2KAK基于 Kakadu 库专有主要实现文件为 frmts/grok/grokdataset.cpp基础类定义在 frmts/grok/grkdatasetbase.h驱动核心元数据/识别在 frmts/grok/jp2grokdrivercore.cpp自动化测试位于 autotest/gdrivers/jp2grok.py。构建依赖Grok 20.2来自 JP2Grok 官方文档 的 build_dependencies 声明。赞分享GIS遥感数据工程【免费下载链接】gdalGDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.项目地址https://gitcode.com/gh_mirrors/gd/gdal点击查看免费下载相关推荐GDAL JP2ECW 驱动完全指南基于 ERDAS ECW/JP2 SDK 的 JPEG2000 读写、地理参考与压缩选项详解GDAL JP2ECW 驱动完全指南基于 ERDAS ECW/JP2 SDK 的 JPEG2000 读写、地理参考与压缩选项详解 本文围绕 GDAL 官方驱动GIS遥感数据工程GDAL FileGDB 驱动详解基于 ESRI File Geodatabase SDK 读写 .gdb 目录GDAL FileGDB 驱动详解基于 ESRI File Geodatabase SDK 读写 .gdb 目录 本文围绕 GDAL 的 FileGDB 向量GIS遥感数据工程ag-ui-spring-server-core 详解AG-UI Spring 服务端的框架无关序列化内核ag ui spring server core 详解AG UI Spring 服务端的框架无关序列化内核 ag ui spring server coreGIS遥感数据工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考