Skip to content

Follow-up #14516: JP2Grok still wrong on Sentinel-2 baseline 05.12 — overview crop + corrupt PL markers #14563

@MathewNWSH

Description

@MathewNWSH

What is the bug?

Hi,

PR #14521 (a8bb17e1) is in the GDAL master I'm building against (verified git merge-base --is-ancestor a8bb17e1 427ba0d4 → yes), but the original symptom is not fixed, and a second class of error appears at higher zoom levels.

Problem 1 — lowest internal overview

from osgeo import gdal
ds = gdal.Open("/vsis3/.../T34UFE_20260511T095031_TCI_10m.jp2")
print(ds.GetDriver().GetDescription())          # → JP2Grok
b = ds.GetRasterBand(1)
print(b.XSize, b.YSize, b.GetOverviewCount())   # → 10980 10980 4
arr = b.GetOverview(3).ReadAsArray()
print(arr.shape, float(arr.mean()))             # → (687, 687) 1.008

Mean 1.008. JP2OpenJPEG on the same file returns the expected ~50–150 range. SIGSEGV on dataset close. Visually (WMS zoom-out): random colored bars scattered across the scene, mostly black canvas (on screen below I tried to mask out the NoData).

Image

With CPL_DEBUG=ON Grok emits only one line for the whole read:

GROK: Full image canvas coordinates:

Problem 2 — higher-zoom RasterIO

Once browser zooms in (tiles between full-res and a non-internal overview), logs fill with:

ERROR 1: Corrupt PL marker reports 20142 bytes for packet; parsed bytes are in fact 1
Warning 1: Corrupt packet: tile=0 component=01 resolution=04 precinct=000 layer=00
ERROR 1: Corrupt PL marker reports 20481 bytes for packet; parsed bytes are in fact 1
Warning 1: Corrupt packet: tile=0 component=01 resolution=04 precinct=001 layer=00
ERROR 1: Corrupt PL marker reports 19770 bytes for packet; parsed bytes are in fact 1
Warning 1: Corrupt packet: tile=0 component=02 resolution=04 precinct=000 layer=00
ERROR 1: Corrupt PL marker reports 21460 bytes for packet; parsed bytes are in fact 49
Warning 1: Corrupt packet: tile=0 component=02 resolution=04 precinct=001 layer=00

Every component/precinct at resolution=04 fails. Output again mostly black. Looks like the selective-fetch / PLT-aware byte-range path is reading wrong ranges, then the parser sees the declared PLT length vs what it actually got.

Steps to reproduce the issue

File uploaded to my S3 sample bucket (URL in #14516). Happy to bisect Grok master if useful.

https://s3.waw3-1.cloudferro.com/swift/v1/s2samples/T34UFE_20260511T095031_TCI_10m.jp2
  • GDAL master 427ba0d4 (2026-05-11), reports 3.14.0dev.
  • Grok master 135008a6 (2026-05-10), built from source.
  • OpenJPEG 2.5.3. Both JP2 drivers compiled. Switching via GDAL_SKIP.
  • Sentinel-2 L2A baseline 0512 TCI 10m JP2 (TLM + PLT, LRCP 1-layer, 121 tile-parts, 10980×10980) (linked above).

With GDAL_SKIP=JP2Grok (JP2OpenJPEG) both zoom levels render correctly on the same files / same GDAL build. Slow cold (~7–10 s), but pixel-correct:

Image

Versions and provenance

  • GDAL: master @ 427ba0d4a7363371cdccf67f2dbdca38db0446ff (2026-05-11),
    reports 3.14.0dev. Built from source. Contains a8bb17e1 (PR JP2Grok: scale overview coords up to full resolution before calling Grok #14521)
    — verified git merge-base --is-ancestor a8bb17e1 427ba0d4 → yes.
  • Grok: master @ 135008a65d2ec042e207f9bb589dd4cfd9ff1247 (2026-05-10).
    Built from source (CMake, SPDLOG_FMT_EXTERNAL=ON, BUILD_SHARED_LIBS=ON,
    with public submodules google/highway, CLIUtils/CLI11, gabime/spdlog).
  • OpenJPEG: 2.5.3 (upstream v2.5.3 tarball).
  • rasterio: 1.5.0 linked against the same GDAL build (no PyPI wheel).
  • Both JP2 drivers compiled in (GDAL_USE_OPENJPEG=ON,
    GDAL_USE_GROK=ON). Switching at runtime via GDAL_SKIP
    (JP2OpenJPEG to use Grok, JP2Grok to use OpenJPEG).
  • OS: Linux 6.19.11-x64v3-xanmod1, glibc 2.42, gcc 15.2.0.
  • Build env: Nix (nixpkgs 566acc07c54dc807f91625bb286cb9b321b5f42a),
    Python 3.13.12.
  • GDAL env at runtime:
    GDAL_SKIP=JP2OpenJPEG
    GDAL_DISABLE_READDIR_ON_OPEN=EMPTY_DIR
    GDAL_HTTP_TCP_KEEPALIVE=YES
    GDAL_HTTP_UNSAFESSL=YES
    GDAL_NUM_THREADS=ALL_CPUS
    GDAL_FORCE_CACHING=YES
    GDAL_CACHEMAX=10%
    GDAL_INGESTED_BYTES_AT_OPEN=1048576
    VSI_CACHE=TRUE, VSI_CACHE_SIZE=268435456
    CPL_VSIL_CURL_CHUNK_SIZE=2097152
    CPL_VSIL_CURL_CACHE_SIZE=33554432
    CPL_VSIL_CURL_ALLOWED_EXTENSIONS=jp2,tif,tiff,fgb
    AWS_S3_ENDPOINT=eodata.cloudferro.com, AWS_REQUEST_PAYER=requester,
    AWS_VIRTUAL_HOSTING=FALSE, AWS_HTTPS=YES

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    not for AI loversSee https://gdal.org/en/stable/community/ai_tool_policy.html

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions