From 7e3110d296a26e0d12e40d0b221f437ffb0628d7 Mon Sep 17 00:00:00 2001 From: Zach Nelson Date: Wed, 20 May 2026 08:43:21 -0500 Subject: [PATCH] chore: Replace JPEGDEC patch script with in-org fork --- platformio.ini | 3 +- .../0001-redirect-pmcu-on-mcu-skip.patch | 28 ------ .../0002-guard-dc-writes-on-mcu-skip.patch | 41 --------- scripts/patch_jpegdec.py | 92 ------------------- 4 files changed, 1 insertion(+), 163 deletions(-) delete mode 100644 scripts/jpegdec_patches/0001-redirect-pmcu-on-mcu-skip.patch delete mode 100644 scripts/jpegdec_patches/0002-guard-dc-writes-on-mcu-skip.patch delete mode 100644 scripts/patch_jpegdec.py diff --git a/platformio.ini b/platformio.ini index 39a526d0..c34df816 100644 --- a/platformio.ini +++ b/platformio.ini @@ -52,7 +52,6 @@ extra_scripts = pre:scripts/build_html.py pre:scripts/gen_i18n.py pre:scripts/git_branch.py - pre:scripts/patch_jpegdec.py ; Libraries lib_deps = @@ -63,7 +62,7 @@ lib_deps = bblanchon/ArduinoJson @ 7.4.2 ricmoo/QRCode @ 0.0.1 bitbank2/PNGdec @ ^1.0.0 - https://github.com/bitbank2/JPEGDEC.git#86282979224c8a32fd51e091ed5a35b0c699a52b + https://github.com/crosspoint-reader/JPEGDEC.git#dac4cfec6eec23289e7fd9f08e1e796cb3c5ef60 links2004/WebSockets @ 2.7.3 [env:default] diff --git a/scripts/jpegdec_patches/0001-redirect-pmcu-on-mcu-skip.patch b/scripts/jpegdec_patches/0001-redirect-pmcu-on-mcu-skip.patch deleted file mode 100644 index 5f046627..00000000 --- a/scripts/jpegdec_patches/0001-redirect-pmcu-on-mcu-skip.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 5dff5afab0c68d0d0c4385d72e6f0c030b613960 Mon Sep 17 00:00:00 2001 -From: patch -Date: Mon, 18 May 2026 20:57:54 -0700 -Subject: [PATCH 1/2] Redirect pMCU to sMCUs[0] when iMCU < 0 (MCU_SKIP) - ---- - src/jpeg.inl | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/jpeg.inl b/src/jpeg.inl -index a60b548..26bcf6f 100644 ---- a/src/jpeg.inl -+++ b/src/jpeg.inl -@@ -1824,7 +1824,10 @@ static int JPEGDecodeMCU_P(JPEGIMAGE *pJPEG, int iMCU, int *iDCPredictor) - unsigned short *pFast; - uint32_t usHuff; // this prevents an unnecessary & 65535 for shorts - signed int iPositive, iNegative, iCoeff; -- signed short *pMCU = &pJPEG->sMCUs[iMCU & 0xffffff]; -+ // CrossPoint patch: redirect pMCU to sMCUs[0] when MCU_SKIP to avoid -+ // a wild pointer (~33 MB past sMCUs) that store-faults on AC writes. -+ signed short *pMCU = (iMCU < 0) ? pJPEG->sMCUs -+ : &pJPEG->sMCUs[iMCU & 0xffffff]; - uint32_t ulBitOff; - my_ulong ulCode, ulBits, ulTemp; // local copies to allow compiler to use register vars - uint8_t *pBuf; --- -2.50.1 (Apple Git-155) - diff --git a/scripts/jpegdec_patches/0002-guard-dc-writes-on-mcu-skip.patch b/scripts/jpegdec_patches/0002-guard-dc-writes-on-mcu-skip.patch deleted file mode 100644 index 82925c64..00000000 --- a/scripts/jpegdec_patches/0002-guard-dc-writes-on-mcu-skip.patch +++ /dev/null @@ -1,41 +0,0 @@ -From f6238b54c2de34c8e29b0d371a7e902d9cf579bf Mon Sep 17 00:00:00 2001 -From: patch -Date: Mon, 18 May 2026 20:58:22 -0700 -Subject: [PATCH 2/2] Guard pMCU[0] DC writes against MCU_SKIP - ---- - src/jpeg.inl | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/src/jpeg.inl b/src/jpeg.inl -index 26bcf6f..1bd38b2 100644 ---- a/src/jpeg.inl -+++ b/src/jpeg.inl -@@ -1855,7 +1855,11 @@ static int JPEGDecodeMCU_P(JPEGIMAGE *pJPEG, int iMCU, int *iDCPredictor) - { - // (*iDCPredictor) |= iPositive; // in case the scan is run more than once - // pMCU[0] = *iDCPredictor; // store in MCU[0] -- pMCU[0] |= iPositive; -+ // CrossPoint patch: guard against MCU_SKIP. The pMCU -+ // redirect makes &sMCUs[0] safe to dereference, but -+ // writing here would clobber the just-decoded Y DC. -+ if (iMCU >= 0) -+ pMCU[0] |= iPositive; - } - goto mcu_done; // that's it - } -@@ -1887,7 +1891,10 @@ static int JPEGDecodeMCU_P(JPEGIMAGE *pJPEG, int iMCU, int *iDCPredictor) - ulCode <<= pJPEG->cApproxBitsLow; // successive approximation shift value - (*iDCPredictor) += ulCode; - } -- pMCU[0] = (short)*iDCPredictor; // store in MCU[0] -+ // CrossPoint patch: guard against MCU_SKIP. See note on the -+ // matching SA write above. -+ if (iMCU >= 0) -+ pMCU[0] = (short)*iDCPredictor; // store in MCU[0] - } - // Now get the other 63 AC coefficients - pFast = &pJPEG->usHuffAC[pJPEG->ucACTable * HUFF11SIZE]; --- -2.50.1 (Apple Git-155) - diff --git a/scripts/patch_jpegdec.py b/scripts/patch_jpegdec.py deleted file mode 100644 index 8f2d38b8..00000000 --- a/scripts/patch_jpegdec.py +++ /dev/null @@ -1,92 +0,0 @@ -""" -PlatformIO pre-build script: apply CrossPoint's JPEGDEC patches via `git apply`. - -The upstream JPEGDEC pin still has the wild-pointer + DC-write bugs in -JPEGDecodeMCU_P that surface when EIGHT_BIT_GRAYSCALE decodes a 3-component -progressive JPEG (each Y MCU drags two MCU_SKIP calls behind it for Cb/Cr). -The patches in `scripts/jpegdec_patches/` carry the fix; this script applies -each one against the libdep working tree. - -Each patch's idempotency is decided by git itself: - * `git apply --check --reverse` succeeds -> already applied, skip - * `git apply --check` succeeds -> apply - * neither succeeds -> abort the build - -Patches live in `scripts/jpegdec_patches/` as one-commit-per-fix files -(see the file headers for context). Applied in lexical order. -""" - -Import("env") # noqa: F821 (SCons-injected global) -import os -import subprocess -import sys - - -PATCH_DIR = os.path.join(env["PROJECT_DIR"], "scripts", "jpegdec_patches") # noqa: F821 - - -def patch_jpegdec(env): - libdeps_dir = os.path.join(env["PROJECT_DIR"], ".pio", "libdeps") - if not os.path.isdir(libdeps_dir): - return - patches = _patch_files() - for env_dir in os.listdir(libdeps_dir): - jpeg_dir = os.path.join(libdeps_dir, env_dir, "JPEGDEC") - if not os.path.isdir(os.path.join(jpeg_dir, ".git")): - continue - for patch in patches: - _apply_one(jpeg_dir, patch) - - -def _patch_files(): - if not os.path.isdir(PATCH_DIR): - raise RuntimeError( - "JPEGDEC patches missing -- aborting build (expected directory %s)" - % PATCH_DIR - ) - patches = sorted( - os.path.join(PATCH_DIR, name) - for name in os.listdir(PATCH_DIR) - if name.endswith(".patch") - ) - if not patches: - raise RuntimeError( - "JPEGDEC patches missing -- aborting build (no .patch files in %s)" - % PATCH_DIR - ) - return patches - - -def _apply_one(jpeg_dir, patch_path): - name = os.path.basename(patch_path) - if _git_apply_succeeds(jpeg_dir, patch_path, reverse=True): - return - if not _git_apply_succeeds(jpeg_dir, patch_path, reverse=False): - # Not applied, not appliable -- the libdep source has diverged from - # what the patch expects. Don't write a half-patched file. - result = subprocess.run( - ["git", "apply", "--check", patch_path], - cwd=jpeg_dir, - capture_output=True, - text=True, - ) - sys.stderr.write( - "ERROR: JPEGDEC patch %s does not apply cleanly:\n%s%s\n" - % (name, result.stdout, result.stderr) - ) - raise SystemExit(1) - subprocess.run(["git", "apply", patch_path], cwd=jpeg_dir, check=True) - print("Applied JPEGDEC patch: %s" % name) - - -def _git_apply_succeeds(jpeg_dir, patch_path, *, reverse): - cmd = ["git", "apply", "--check"] - if reverse: - cmd.append("--reverse") - cmd.append(patch_path) - return subprocess.run( - cmd, cwd=jpeg_dir, capture_output=True, text=True - ).returncode == 0 - - -patch_jpegdec(env) # noqa: F821