From 8cbb071261dc9031106770dace97ee2fe9347856 Mon Sep 17 00:00:00 2001
From: Sergio Gonzalez Martin <sergiog@microsoft.com>
Date: Mon, 17 Aug 2026 14:30:18 +0000
Subject: [PATCH 3/4] feat(jpeg): parse 12-bit Huffman headers

Backport of https://github.com/etemesi254/zune-image/pull/432.

---
diff --git a/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/decoder.rs b/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/decoder.rs
index 8132b7d464003..8c1af6e108e58 100644
--- a/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/decoder.rs
+++ b/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/decoder.rs
@@ -652,6 +652,7 @@ where
     /// See DecodeErrors for an explanation
     pub fn decode(&mut self) -> Result<Vec<u8>, DecodeErrors> {
         self.decode_headers()?;
+        self.ensure_supported_sample_precision()?;
 
         if self.expects_dnl {
             // Height is unknown until DNL is encountered during entropy
@@ -724,7 +725,7 @@ where
     ///
     /// # Returns
     ///  - `Some(usize)`: Minimum size for a buffer needed to decode the image
-    ///  - `None`: Indicates the image was not decoded, or image dimensions would overflow a usize
+    ///  - `None`: Indicates headers are unavailable or image dimensions overflow `usize`
     ///
     #[must_use]
     pub fn output_buffer_size(&self) -> Option<usize> {
@@ -1224,8 +1225,9 @@ where
                 // choose marker
                 let (marker, is_progressive) =
                     match m {
-                        Marker::SOF(0 | 1) =>
-                            (SOFMarkers::BaselineDct, false),
+                        Marker::SOF(0) => (SOFMarkers::BaselineDct, false),
+                        Marker::SOF(1) =>
+                            (SOFMarkers::ExtendedSequentialHuffman, false),
                         Marker::SOF(2) =>
                             (SOFMarkers::ProgressiveDctHuffman, true),
                         _ => unreachable!(),
@@ -1508,6 +1510,15 @@ where
         };
     }
 
+    fn ensure_supported_sample_precision(&self) -> Result<(), DecodeErrors> {
+        if self.info.pixel_density == 12 {
+            return Err(DecodeErrors::FormatStatic(
+                "12-bit JPEG pixel decoding is not supported"
+            ));
+        }
+        Ok(())
+    }
+
     /// Decode into a pre-allocated buffer
     ///
     /// It is an error if the buffer size is smaller than
@@ -1706,6 +1717,8 @@ where
             self.decode_headers_internal()?;
         }
 
+        self.ensure_supported_sample_precision()?;
+
         let expected_size = self.output_buffer_size().unwrap();
 
         if out.len() < expected_size {
@@ -1912,7 +1925,7 @@ pub struct ImageInfo {
     pub width: u16,
     /// Height of image
     pub height: u16,
-    /// PixelDensity
+    /// Sample precision in bits.
     pub pixel_density: u8,
     /// Start of frame markers
     pub sof: SOFMarkers,
diff --git a/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/headers.rs b/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/headers.rs
index af9ee203f5d7c..03a91b50ba900 100644
--- a/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/headers.rs
+++ b/third_party/rust/chromium_crates_io/vendor/zune-jpeg-v0_5/src/headers.rs
@@ -332,13 +332,20 @@ pub(crate) fn parse_start_of_frame<T: ZByteReaderTrait>(
         // Body length came from a u16 length field minus 2; +2 round-trips it.
         #[allow(clippy::cast_possible_truncation)]
         let length = (cursor.body().len() + 2) as u16;
-        // usually 8, but can be 12 and 16, we currently support only 8
-        // so sorry about that 12 bit images
+        // Pixel decoding remains 8-bit only, but Huffman-coded 12-bit frame
+        // headers are useful to callers that inspect image metadata.
         let dt_precision = cursor.read_u8()?;
 
-        if dt_precision != 8 {
+        let supported_header_precision = dt_precision == 8
+            || (dt_precision == 12
+                && matches!(
+                    sof,
+                    SOFMarkers::ExtendedSequentialHuffman
+                        | SOFMarkers::ProgressiveDctHuffman
+                ));
+        if !supported_header_precision {
             return Err(DecodeErrors::SofError(format!(
-                "The library can only parse 8-bit images, the image has {dt_precision} bits of precision"
+                "Unsupported {dt_precision}-bit sample precision for {sof:?}"
             )));
         }
 
-- 
git version 2.55.0
