diff --git a/crates/raw/src/llvc.rs b/crates/raw/src/llvc.rs index fee6f4388..ef5258910 100644 --- a/crates/raw/src/llvc.rs +++ b/crates/raw/src/llvc.rs @@ -3,9 +3,6 @@ //! Clean-room: written from SMPTE RDD 34:2015 §6.3 (Figures 6.5-6.8) and checked against its worked //! example (Figure 6.9) and Phase 0 oracle vectors. No other raw decoder's source was consulted. -// Consumed by the dequantiser/wavelet/ARW6 container tasks that follow. -#![allow(dead_code)] - use crate::vendor::pef::Bits; use crate::{RawError, Result}; diff --git a/crates/raw/src/vendor/arw.rs b/crates/raw/src/vendor/arw.rs index d80c67f84..f7dc1831b 100644 --- a/crates/raw/src/vendor/arw.rs +++ b/crates/raw/src/vendor/arw.rs @@ -36,10 +36,13 @@ //! bytes): plain 12-bit samples, two per three bytes, least-significant-bit first ([`unpack_row12`]); linear, black 128 //! (512 on the 14-bit scale), CFA from the file's own pattern tag, crop centred on the frame (see [`default_crop`]). //! +//! ARW6 (Compressed RAW 2, compression 32766): `arw6.rs`, output in 2 × 14-bit units. +//! //! Also: uncompressed 16-bit ARW, and lossless-compressed ARW (Compression 7, ILCE-7M4 and later): LJ92 tiles whose //! frames hold one 2×2 CFA cell per four-component sample ([`read_quad_tiles`]). Other lossless-JPEG layouts go //! through the generic TIFF path. +use super::arw6; use crate::tiffraw::{Packing, check_image, read_image_in}; use crate::{BlackLevel, Cfa, ColorData, Mode, OpcodeLists, RawData, RawError, RawFormat, RawImage, Rect, Result, ljpeg}; use lightcraft_geom::Orientation; @@ -609,6 +612,11 @@ pub(crate) fn decode(bytes: &[u8], mode: Mode) -> Result { (RawData::U16(Vec::new()), bits) } }, + 32766 if chunks.len() == 1 => { + let src = chunk_bytes(bytes, &chunks[0]).ok_or_else(|| RawError::Corrupt("raw strip outside file".into()))?; + (RawData::U16(arw6::decode(src, w, h, mode)?), 16) + } + 32766 => return Err(RawError::Unsupported("ARW6 with more than one strip".into())), 1 => { let word16 = strip_len >= (w * h * 2) as u64; let packing = if word16 { Packing::Word16 } else { Packing::Msb }; @@ -651,6 +659,10 @@ pub(crate) fn decode(bytes: &[u8], mode: Mode) -> Result { } else { raw.f64(t::WHITE_LEVEL).map(|v| v as f32).filter(|v| *v > 0.0).unwrap_or_else(|| super::white_from_data(samples, scale_bits)) }; + // ARW6 samples are in 2 x 14-bit units, so the file's 14-bit levels double + let unit = if info.compression == 32766 { 2.0 } else { 1.0 }; + let black = BlackLevel { values: black.values.iter().map(|v| v * unit).collect(), ..black }; + let white = white * unit; let model = ifd0.string(t::MODEL).unwrap_or_default(); let mn = tiff .exif() diff --git a/crates/raw/src/vendor/arw6.rs b/crates/raw/src/vendor/arw6.rs index 49f0ebc31..4d9cf1651 100644 --- a/crates/raw/src/vendor/arw6.rs +++ b/crates/raw/src/vendor/arw6.rs @@ -5,10 +5,8 @@ //! checked by re-serialising parsed tiles byte-for-byte; see `docs/superpowers/specs/2026-10-09-sony-arw6-decoder-design.md` //! (*Container (Sony)*). No other raw decoder's source was consulted. -// Consumed by the geometry and `decode` tasks that follow. -#![allow(dead_code)] - use crate::llvc::{Bands3, Plane, band_rows, dequant, reconstruct3, vld_decode_line}; +use crate::vendor::arw6_curve::{ARW6_CURVE, CURVE_KNEE}; use crate::vendor::pef::Bits; use crate::{RawError, Result}; use rayon::prelude::*; @@ -433,8 +431,10 @@ pub(crate) fn decode_tile_planes(tile: &[u8], tw: usize, th: usize) -> Result = (0..2 * ntu).map(|n| half_layout(n, s, vs, ph)).collect(); - let streams = h.streams.par_iter().map(|st| decode_stream(tile, st, ntu, w2, &layouts)).collect::>>()?; - let comps = (0..3).into_par_iter().map(|c| component(c, &streams, &layouts, vs, w2, ph)).collect::>>()?; + let streams = + h.streams.par_iter().map(|st| decode_stream(tile, st, ntu, w2, &layouts)).collect::>().into_iter().collect::>>()?; + let comps = + (0..3).into_par_iter().map(|c| component(c, &streams, &layouts, vs, w2, ph)).collect::>().into_iter().collect::>>()?; // Residual: g4's lines are the half's plane rows, dequantised with the half's nibble. let mut res = Plane::zeros(w2, vs); for ((half, lines), r) in streams.get(12).ok_or_else(|| corrupt("missing residual stream"))?.iter().zip(&layouts) { @@ -447,10 +447,99 @@ pub(crate) fn decode_tile_planes(tile: &[u8], tw: usize, th: usize) -> Result u16 { + let c = code12.clamp(0, 4095) as usize; + match c.checked_sub(CURVE_KNEE) { + None => c as u16, + Some(i) => ARW6_CURVE.get(i).copied().unwrap_or(39002), + } +} + +/// Colour reconstruction (spec *Colour reconstruction*, checked against Phase 0 oracle output): the planes give a +/// `(2 W2) x (2 H2)` mosaic with R at (0,0), G1 (0,1), G2 (1,0), B (1,1) of every 2x2 cell, each value passed through +/// [`curve`]. G1 comes from the green mean minus a residual average, G2 is predicted from the (unclipped) G1 plus the +/// residual, and R/B are chroma plus the mean of the greens clipped to 12 bits. +pub(crate) fn colour(p: &TilePlanes) -> Result> { + let (w2, h2) = (p.m.width, p.m.height); + let len = w2.checked_mul(h2).ok_or_else(|| corrupt("tile size"))?; + if [&p.c1, &p.c2, &p.res].iter().any(|q| q.width != w2 || q.height != h2 || q.data.len() != len) || p.m.data.len() != len { + return Err(corrupt("plane size mismatch")); + } + let mw = w2.checked_mul(2).ok_or_else(|| corrupt("tile size"))?; + let total = len.checked_mul(4).ok_or_else(|| corrupt("tile size"))?; + let at = |q: &Plane, j: usize, x: usize| -> i64 { q.data.get(j * w2 + x).copied().unwrap_or(0) as i64 }; + let mut g1 = vec![0i64; len]; + for j in 0..h2 { + let jp = j.saturating_sub(1); + for x in 0..w2 { + let xn = (x + 1).min(w2 - 1); + let r = at(&p.res, jp, x) + at(&p.res, jp, xn) + at(&p.res, j, x) + at(&p.res, j, xn); + if let Some(g) = g1.get_mut(j * w2 + x) { + *g = at(&p.m, j, x) - ((r + 4) >> 3); + } + } + } + let g = |j: usize, x: usize| g1.get(j * w2 + x).copied().unwrap_or(0); + let mut out = vec![0u16; total]; + for j in 0..h2 { + let jn = (j + 1).min(h2 - 1); + for x in 0..w2 { + let xp = x.saturating_sub(1); + let g2 = ((g(j, xp) + g(j, x) + g(jn, xp) + g(jn, x)) >> 2) + at(&p.res, j, x); + let mean = (g(j, x).min(4095) + g2.min(4095)) >> 1; + let r = 2 * at(&p.c1, j, x) + mean; + let b = 2 * at(&p.c2, j, x) + mean; + let cells = [(0, r), (1, g(j, x)), (mw, g2), (mw + 1, b)]; + for (off, v) in cells { + if let Some(o) = out.get_mut(2 * j * mw + 2 * x + off) { + *o = curve(v.clamp(0, 4095) as i32); + } + } + } + } + Ok(out) +} + +/// One tile to its `tw x th` mosaic in output units. +pub(crate) fn decode_tile(tile: &[u8], tw: usize, th: usize) -> Result> { + colour(&decode_tile_planes(tile, tw, th)?) +} + +/// Decode a whole ARW6 strip: [`Mode::Header`](crate::Mode) validates the tile table, tile headers and stream +/// tables and returns no samples; `Full` decodes the tiles in parallel into a `width x height` mosaic. +pub(crate) fn decode(strip: &[u8], width: usize, height: usize, mode: crate::Mode) -> Result> { + let tiles = parse_tile_table(strip, width, height)?; + let bytes = |i: usize| tile_bytes(strip, &tiles, i).ok_or_else(|| corrupt("tile outside strip")); + if mode == crate::Mode::Header { + for (i, t) in tiles.iter().enumerate() { + let tile = bytes(i)?; + let h = parse_tile_header(tile, t.width, t.height)?; + let g4 = h.streams.get(12).ok_or_else(|| corrupt("missing residual stream"))?; + let s = first_half_shift(tile, g4, t.width / 2)?; + let ntu = tu_count(h.vs, s); + for st in &h.streams { + stream_halves(tile, st, ntu)?; + } + } + return Ok(Vec::new()); + } + let decoded: Vec>> = tiles.par_iter().enumerate().map(|(i, t)| decode_tile(bytes(i)?, t.width, t.height)).collect(); + let mut out = vec![0u16; width.checked_mul(height).ok_or_else(|| corrupt("image size"))?]; + for (t, d) in tiles.iter().zip(decoded) { + let d = d?; + for (r, row) in d.chunks_exact(t.width.max(1)).enumerate() { + let start = (t.y + r).checked_mul(width).and_then(|a| a.checked_add(t.x)).ok_or_else(|| corrupt("tile placement"))?; + let dst = start.checked_add(row.len()).and_then(|end| out.get_mut(start..end)).ok_or_else(|| corrupt("tile outside image"))?; + dst.copy_from_slice(row); + } + } + Ok(out) +} + #[cfg(test)] mod tests { use super::*; - use crate::llvc::Plane; use crate::vendor::arw6_testenc::*; use crate::vendor::pef::Bits; use lightcraft_tiff::Tiff; @@ -726,4 +815,102 @@ mod tests { let _ = decode_tile_planes(&tile, 64, 48); } } + + #[test] + fn curve_anchors() { + assert_eq!(ARW6_CURVE.len(), 2668); + for (c, v) in [(0, 0), (1427, 1427), (1428, 1429), (1436, 1438), (2048, 2469), (3000, 8010), (4094, 38944), (4095, 39002)] { + assert_eq!(curve(c), v, "code {c}"); + } + assert_eq!(curve(-5), 0); + assert_eq!(curve(5000), 39002); + assert!(ARW6_CURVE.windows(2).all(|w| w[0] < w[1])); + } + + fn plane(w: usize, v: &[i32]) -> Plane { + Plane { width: w, height: v.len() / w, data: v.to_vec() } + } + + fn example() -> TilePlanes { + TilePlanes { + m: plane(3, &[2048, 2052, 2060, 2050, 2049, 2070]), + res: plane(3, &[4, -8, 2, 0, 2, -6]), + c1: plane(3, &[10, -10, 0, 0, 3, -2]), + c2: plane(3, &[-5, 7, 1, 2, 0, 4]), + } + } + + #[test] + fn colour_matches_the_phase0_example() { + let out = colour(&example()).unwrap(); // 6 wide x 4 rows, curve units + let code = |r: usize, c: usize| out[r * 6 + c] as i32; + assert_eq!( + [code(0, 1), code(0, 3), code(0, 5), code(2, 1), code(2, 3), code(2, 5)], + [2049, 2053, 2059, 2050, 2050, 2071].map(|c| curve(c) as i32) + ); // G1 + assert_eq!( + [code(1, 0), code(1, 2), code(1, 4), code(3, 0), code(3, 2), code(3, 4)], + [2053, 2042, 2060, 2050, 2052, 2054].map(|c| curve(c) as i32) + ); // G2 + assert_eq!([code(0, 0), code(0, 2), code(0, 4)], [2071, 2027, 2059].map(|c| curve(c) as i32)); // R + assert_eq!([code(1, 1), code(1, 3), code(1, 5)], [2041, 2061, 2061].map(|c| curve(c) as i32)); // B + } + + #[test] + fn colour_clips_like_the_oracle() { + let mut p = example(); + p.m.data[1] = 4100; + let out = colour(&p).unwrap(); + assert_eq!(out[3], 39002); // G1 = 4101 -> clipped output + assert_eq!(out[6 + 2], curve(2554)); // G2 predicted from the unclipped G1 + assert_eq!(out[2], curve(3304)); // R = 2*(-10) + ((4095 + 2554) >> 1): chroma uses the clipped greens + } + + #[test] + fn decode_header_and_full_and_truncations() { + let (tile, _) = one_tile(64, 48, 3, Qis::REAL); + let file = arw6_file(&[(0, 0, 64, 48, tile)], 64, 48); + let strip = strip_of(&file); + assert!(decode(strip, 64, 48, crate::Mode::Header).unwrap().is_empty()); + assert_eq!(decode(strip, 64, 48, crate::Mode::Full).unwrap().len(), 64 * 48); + for n in 0..strip.len() { + let _ = decode(&strip[..n], 64, 48, crate::Mode::Full); + let _ = decode(&strip[..n], 64, 48, crate::Mode::Header); + } + } + + #[test] + fn corrupt_streams_import_then_fail() { + // Garbage VLD data is self-delimiting and decodes to *something*; what is detectable is a half whose index + // length is too short for the lines it must hold. + let (mut tile, _) = one_tile(64, 48, 0, Qis::REAL); + let h = parse_tile_header(&tile, 64, 48).unwrap(); + let at = (h.streams[9].word + 1) * 16; // g3 c0 index table, first entry: half 0's byte length (u16 BE) + tile[at] = 0; + tile[at + 1] = 1; + let strip = strip_of(&arw6_file(&[(0, 0, 64, 48, tile)], 64, 48)).to_vec(); + assert!(decode(&strip, 64, 48, crate::Mode::Header).is_ok()); + assert!(matches!(decode(&strip, 64, 48, crate::Mode::Full), Err(RawError::Corrupt(_)))); + } + + #[test] + fn four_tiles_place_correctly_and_arw_reports_doubled_levels() { + let tiles: Vec<_> = [(0, 0), (64, 0), (0, 48), (64, 48)] + .iter() + .map(|&(x, y)| { + let (t, _) = one_tile(64, 48, 0, Qis::ZERO); + (x, y, 64, 48, t) + }) + .collect(); + let file = arw6_file(&tiles, 128, 96); + let img = crate::decode(&file).unwrap(); + assert_eq!((img.width, img.height, img.bits), (128, 96, 16)); + assert_eq!(img.black.values, vec![1024.0; 4]); + assert_eq!(img.white, vec![30720.0]); + assert_eq!(img.cfa.as_ref().map(|c| c.pattern.clone()), Some(vec![0, 1, 1, 2])); + let crate::RawData::U16(d) = img.data else { panic!() }; + let single = decode(strip_of(&arw6_file(&tiles[..1], 64, 48)), 64, 48, crate::Mode::Full).unwrap(); + assert_eq!(&d[..64], &single[..64]); // tile 0's first row lands at (0, 0) + assert_eq!(crate::probe_info(&file).unwrap().width, 128); // header mode: tile tables and headers only + } } diff --git a/crates/raw/src/vendor/arw6_curve.rs b/crates/raw/src/vendor/arw6_curve.rs new file mode 100644 index 000000000..1807195b7 --- /dev/null +++ b/crates/raw/src/vendor/arw6_curve.rs @@ -0,0 +1,176 @@ +//! The ARW6 companding table: 12-bit tile code to output value. + +/// First code the table covers; below it the curve is the identity. +pub(crate) const CURVE_KNEE: usize = 1428; + +/// code → 2 × 14-bit DN; identity below the knee; derived in Phase 0 from the black-box oracle's output over 8 files (0 disagreements), see docs/arw6-compression.md. +#[rustfmt::skip] +pub(crate) const ARW6_CURVE: [u16; 2668] = [ + 1429,1430,1431,1432,1433,1434,1435,1436,1438,1439,1440,1441,1442,1443,1444,1445, + 1446,1447,1448,1449,1450,1451,1452,1453,1455,1456,1457,1458,1459,1460,1461,1462, + 1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478, + 1480,1481,1482,1483,1484,1485,1486,1487,1489,1490,1491,1492,1493,1494,1495,1496, + 1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,1511,1512, + 1513,1514,1515,1516,1517,1518,1519,1520,1522,1523,1524,1525,1526,1527,1529,1530, + 1531,1532,1534,1535,1536,1537,1538,1539,1541,1542,1543,1544,1545,1546,1548,1549, + 1550,1551,1553,1554,1555,1556,1558,1559,1561,1562,1563,1565,1566,1567,1568,1569, + 1571,1572,1573,1574,1575,1576,1578,1579,1580,1581,1583,1584,1585,1586,1588,1589, + 1590,1591,1593,1594,1595,1596,1598,1599,1601,1602,1603,1605,1606,1607,1608,1609, + 1611,1612,1613,1614,1615,1616,1618,1619,1621,1622,1623,1625,1626,1627,1629,1630, + 1631,1632,1634,1635,1636,1637,1639,1640,1641,1642,1644,1645,1646,1647,1649,1650, + 1651,1652,1654,1655,1656,1657,1659,1660,1662,1663,1664,1666,1667,1668,1670,1671, + 1673,1674,1675,1677,1678,1680,1681,1683,1685,1686,1688,1689,1691,1692,1694,1695, + 1697,1698,1699,1701,1702,1704,1705,1707,1709,1710,1712,1713,1715,1716,1718,1719, + 1720,1721,1723,1724,1725,1727,1728,1730,1731,1733,1734,1736,1737,1739,1740,1742, + 1743,1745,1746,1748,1749,1750,1752,1753,1755,1756,1757,1759,1760,1762,1763,1765, + 1767,1768,1770,1771,1773,1774,1776,1777,1779,1780,1781,1783,1784,1786,1787,1789, + 1791,1792,1794,1795,1797,1799,1801,1802,1804,1806,1808,1809,1811,1813,1814,1816, + 1818,1819,1821,1822,1824,1826,1827,1829,1831,1832,1834,1835,1837,1839,1841,1842, + 1844,1846,1848,1849,1851,1853,1854,1856,1858,1859,1861,1862,1864,1866,1868,1869, + 1871,1873,1875,1876,1878,1880,1881,1883,1885,1886,1888,1889,1891,1893,1894,1896, + 1898,1899,1901,1902,1904,1906,1908,1909,1911,1913,1915,1916,1918,1920,1922,1924, + 1926,1927,1929,1931,1933,1935,1937,1938,1940,1942,1944,1945,1947,1949,1951,1953, + 1955,1957,1959,1961,1963,1965,1967,1968,1970,1972,1974,1975,1977,1979,1981,1983, + 1985,1986,1988,1990,1992,1994,1996,1998,2000,2001,2003,2005,2007,2009,2011,2013, + 2015,2016,2018,2020,2022,2024,2026,2027,2029,2031,2033,2034,2036,2038,2040,2042, + 2044,2046,2048,2050,2052,2054,2056,2058,2060,2062,2064,2066,2068,2070,2072,2074, + 2076,2078,2080,2082,2084,2086,2088,2090,2092,2094,2096,2098,2100,2102,2104,2106, + 2109,2111,2113,2115,2117,2119,2121,2123,2125,2127,2129,2131,2133,2135,2137,2139, + 2141,2143,2145,2147,2149,2151,2153,2155,2157,2159,2161,2163,2165,2167,2170,2172, + 2175,2177,2179,2182,2184,2186,2188,2190,2193,2195,2197,2199,2201,2203,2206,2208, + 2210,2212,2215,2217,2219,2221,2224,2226,2228,2230,2233,2235,2237,2239,2242,2244, + 2247,2249,2251,2254,2256,2258,2261,2263,2265,2267,2270,2272,2274,2276,2279,2281, + 2283,2285,2288,2290,2292,2294,2297,2299,2302,2304,2306,2309,2311,2314,2316,2319, + 2321,2324,2326,2329,2331,2333,2336,2338,2340,2342,2345,2347,2349,2352,2354,2357, + 2359,2362,2364,2367,2369,2371,2374,2376,2379,2381,2383,2386,2388,2390,2393,2395, + 2398,2400,2402,2405,2407,2410,2412,2415,2417,2420,2422,2425,2427,2430,2432,2435, + 2438,2440,2443,2445,2448,2451,2453,2456,2459,2461,2464,2466,2469,2472,2475,2477, + 2480,2483,2486,2488,2491,2494,2496,2499,2501,2504,2506,2509,2511,2514,2517,2519, + 2522,2525,2528,2530,2533,2536,2538,2541,2543,2546,2548,2551,2553,2556,2559,2561, + 2564,2567,2570,2572,2575,2578,2581,2584,2587,2589,2592,2595,2598,2601,2604,2606, + 2609,2612,2615,2617,2620,2623,2626,2629,2632,2634,2637,2640,2643,2646,2649,2652, + 2655,2657,2660,2663,2666,2669,2672,2675,2678,2680,2683,2686,2689,2692,2695,2698, + 2701,2704,2707,2710,2713,2716,2719,2722,2725,2727,2730,2733,2736,2739,2742,2745, + 2749,2752,2755,2758,2761,2764,2767,2770,2773,2776,2779,2782,2785,2788,2791,2794, + 2798,2801,2804,2807,2810,2813,2816,2819,2823,2826,2829,2832,2835,2838,2841,2844, + 2848,2851,2854,2857,2860,2863,2867,2870,2873,2876,2880,2883,2886,2889,2893,2896, + 2899,2902,2906,2909,2912,2915,2919,2922,2925,2928,2932,2935,2938,2941,2945,2948, + 2952,2955,2958,2962,2965,2968,2972,2975,2979,2982,2985,2989,2992,2995,2999,3002, + 3006,3009,3012,3016,3019,3023,3026,3030,3033,3037,3040,3044,3047,3051,3054,3058, + 3061,3065,3068,3072,3075,3079,3082,3086,3089,3093,3096,3100,3103,3107,3110,3114, + 3118,3121,3125,3128,3132,3136,3139,3143,3146,3150,3153,3157,3160,3164,3168,3171, + 3175,3179,3183,3186,3190,3194,3197,3201,3205,3208,3212,3215,3219,3223,3227,3231, + 3235,3238,3242,3246,3250,3254,3258,3261,3265,3269,3273,3276,3280,3284,3288,3292, + 3296,3299,3303,3307,3311,3315,3319,3323,3327,3331,3335,3339,3343,3347,3351,3354, + 3358,3362,3366,3369,3373,3377,3381,3385,3389,3393,3397,3401,3405,3409,3413,3417, + 3422,3426,3430,3434,3438,3442,3446,3450,3455,3459,3463,3467,3471,3475,3479,3483, + 3487,3491,3495,3499,3503,3507,3512,3516,3520,3524,3529,3533,3537,3541,3546,3550, + 3554,3558,3563,3567,3571,3575,3580,3584,3589,3593,3597,3602,3606,3610,3615,3619, + 3624,3628,3632,3637,3641,3645,3650,3654,3658,3662,3667,3671,3675,3680,3684,3689, + 3693,3698,3702,3707,3711,3716,3720,3725,3729,3734,3738,3743,3747,3752,3756,3761, + 3766,3770,3775,3779,3784,3789,3793,3798,3802,3807,3811,3816,3820,3825,3830,3834, + 3839,3844,3849,3853,3858,3863,3868,3872,3877,3882,3887,3891,3896,3901,3906,3910, + 3915,3920,3925,3929,3934,3939,3944,3949,3954,3958,3963,3968,3973,3978,3983,3988, + 3993,3997,4002,4007,4012,4017,4022,4027,4032,4037,4042,4047,4052,4057,4062,4067, + 4072,4077,4082,4087,4092,4097,4102,4107,4113,4118,4123,4128,4133,4138,4143,4148, + 4154,4159,4164,4169,4174,4179,4185,4190,4195,4200,4206,4211,4216,4221,4227,4232, + 4237,4242,4248,4253,4258,4263,4269,4274,4280,4285,4290,4296,4301,4306,4312,4317, + 4323,4328,4333,4339,4344,4350,4355,4361,4366,4372,4377,4383,4388,4394,4399,4405, + 4410,4416,4421,4427,4432,4438,4444,4449,4455,4461,4467,4472,4478,4484,4489,4495, + 4500,4506,4511,4517,4522,4528,4534,4540,4546,4551,4557,4563,4569,4575,4581,4586, + 4592,4598,4604,4609,4615,4621,4627,4633,4639,4644,4650,4656,4662,4668,4674,4680, + 4686,4692,4698,4704,4710,4716,4722,4728,4734,4740,4746,4752,4758,4764,4771,4777, + 4783,4789,4796,4802,4808,4814,4820,4826,4832,4838,4844,4850,4856,4862,4869,4875, + 4882,4888,4894,4901,4907,4913,4920,4926,4933,4939,4945,4952,4958,4964,4971,4977, + 4983,4989,4996,5002,5008,5015,5021,5028,5034,5041,5047,5054,5060,5067,5073,5080, + 5087,5093,5100,5106,5113,5120,5126,5133,5140,5146,5153,5159,5166,5173,5180,5186, + 5193,5200,5207,5213,5220,5227,5234,5240,5247,5254,5261,5267,5274,5281,5288,5295, + 5302,5309,5316,5323,5330,5337,5344,5351,5358,5365,5372,5379,5386,5393,5400,5407, + 5414,5421,5428,5435,5442,5449,5456,5463,5471,5478,5485,5492,5499,5506,5514,5521, + 5528,5535,5543,5550,5557,5564,5572,5579,5587,5594,5601,5609,5616,5623,5631,5638, + 5646,5653,5660,5668,5675,5683,5690,5698,5705,5713,5720,5728,5735,5743,5751,5758, + 5766,5774,5782,5789,5797,5805,5812,5820,5828,5835,5843,5850,5858,5866,5874,5881, + 5889,5897,5905,5912,5920,5928,5936,5944,5952,5959,5967,5975,5983,5991,5999,6007, + 6015,6023,6031,6039,6047,6055,6063,6071,6079,6087,6095,6103,6111,6119,6128,6136, + 6144,6152,6161,6169,6177,6185,6194,6202,6210,6218,6227,6235,6243,6251,6260,6268, + 6277,6285,6293,6302,6310,6319,6327,6336,6344,6353,6361,6370,6378,6387,6395,6404, + 6412,6421,6429,6438,6446,6455,6464,6472,6481,6490,6499,6507,6516,6525,6534,6543, + 6552,6560,6569,6578,6587,6596,6605,6613,6622,6631,6640,6648,6657,6666,6675,6684, + 6694,6703,6712,6721,6730,6739,6748,6757,6767,6776,6785,6794,6803,6812,6822,6831, + 6840,6849,6859,6868,6877,6886,6896,6905,6914,6923,6933,6942,6951,6961,6970,6980, + 6989,6999,7008,7018,7027,7037,7046,7056,7065,7075,7084,7094,7103,7113,7123,7132, + 7142,7152,7162,7171,7181,7191,7201,7210,7220,7230,7240,7249,7259,7269,7279,7289, + 7299,7309,7319,7329,7339,7349,7359,7369,7379,7389,7399,7409,7419,7429,7440,7450, + 7460,7470,7481,7491,7501,7511,7522,7532,7543,7553,7563,7574,7584,7594,7605,7615, + 7626,7636,7646,7657,7667,7678,7688,7699,7709,7720,7730,7741,7751,7762,7772,7783, + 7794,7804,7815,7825,7836,7847,7858,7869,7880,7890,7901,7912,7923,7934,7945,7956, + 7967,7977,7988,7999,8010,8021,8032,8043,8055,8066,8077,8088,8099,8110,8122,8133, + 8144,8155,8167,8178,8189,8200,8212,8223,8234,8245,8257,8268,8279,8291,8302,8314, + 8326,8337,8349,8360,8372,8384,8395,8407,8418,8430,8441,8453,8464,8476,8488,8500, + 8512,8523,8535,8547,8559,8571,8583,8595,8607,8618,8630,8642,8654,8666,8678,8690, + 8702,8714,8726,8738,8750,8762,8775,8787,8799,8811,8824,8836,8848,8860,8873,8885, + 8898,8910,8922,8935,8947,8960,8972,8985,8997,9010,9022,9035,9047,9060,9072,9085, + 9098,9110,9123,9135,9148,9161,9174,9187,9200,9212,9225,9238,9251,9264,9277,9290, + 9303,9316,9329,9342,9355,9368,9381,9394,9408,9421,9434,9447,9460,9473,9487,9500, + 9513,9526,9540,9553,9566,9580,9593,9607,9620,9634,9647,9661,9674,9688,9701,9715, + 9728,9742,9755,9769,9782,9796,9810,9824,9838,9851,9865,9879,9893,9907,9921,9935, + 9949,9963,9977,9991,10005,10019,10033,10047,10061,10075,10089,10103,10117,10131,10146,10160, + 10175,10189,10203,10218,10232,10247,10261,10276,10290,10305,10319,10334,10348,10363,10377,10392, + 10407,10421,10436,10450,10465,10480,10495,10509,10524,10539,10554,10568,10583,10598,10613,10628, + 10643,10658,10673,10688,10703,10718,10734,10749,10764,10779,10795,10810,10825,10840,10856,10871, + 10887,10902,10917,10933,10948,10964,10979,10995,11010,11026,11041,11057,11072,11088,11104,11120, + 11136,11151,11167,11183,11199,11215,11231,11247,11263,11278,11294,11310,11326,11342,11358,11374, + 11391,11407,11423,11439,11455,11471,11488,11504,11521,11537,11553,11570,11586,11603,11619,11636, + 11652,11669,11685,11702,11718,11735,11752,11768,11785,11802,11819,11835,11852,11869,11886,11903, + 11920,11937,11954,11971,11988,12005,12022,12039,12057,12074,12091,12108,12125,12142,12160,12177, + 12195,12212,12229,12247,12264,12282,12299,12317,12335,12352,12370,12387,12405,12423,12441,12458, + 12476,12494,12512,12529,12547,12565,12583,12601,12619,12637,12655,12673,12691,12709,12728,12746, + 12764,12782,12801,12819,12837,12855,12874,12892,12911,12929,12947,12966,12984,13003,13022,13040, + 13059,13078,13097,13115,13134,13153,13172,13191,13210,13228,13247,13266,13285,13304,13323,13342, + 13362,13381,13400,13419,13438,13457,13477,13496,13516,13535,13554,13574,13593,13613,13632,13652, + 13672,13691,13711,13730,13750,13770,13790,13810,13830,13849,13869,13889,13909,13929,13949,13969, + 13990,14010,14030,14050,14070,14090,14111,14131,14151,14171,14192,14212,14232,14253,14273,14294, + 14315,14335,14356,14376,14397,14418,14439,14460,14481,14501,14522,14543,14564,14585,14606,14627, + 14648,14669,14690,14711,14732,14753,14775,14796,14818,14839,14860,14882,14903,14925,14946,14968, + 14990,15011,15033,15054,15076,15098,15120,15142,15164,15185,15207,15229,15251,15273,15295,15317, + 15340,15362,15384,15406,15428,15450,15473,15495,15518,15540,15562,15585,15607,15630,15653,15675, + 15698,15721,15744,15766,15789,15812,15835,15858,15881,15903,15926,15949,15972,15995,16019,16042, + 16065,16088,16112,16135,16158,16182,16205,16229,16253,16276,16300,16323,16347,16371,16395,16418, + 16442,16466,16490,16513,16537,16561,16585,16609,16634,16658,16682,16706,16730,16754,16779,16803, + 16828,16852,16876,16901,16925,16950,16975,16999,17024,17049,17074,17098,17123,17148,17173,17198, + 17223,17248,17273,17298,17323,17348,17374,17399,17424,17449,17475,17500,17525,17551,17576,17602, + 17628,17653,17679,17704,17730,17756,17782,17808,17834,17860,17886,17912,17938,17964,17991,18017, + 18043,18069,18096,18122,18148,18175,18201,18228,18254,18281,18307,18334,18360,18387,18414,18441, + 18468,18494,18521,18548,18575,18602,18630,18657,18684,18711,18739,18766,18793,18821,18848,18876, + 18904,18931,18959,18986,19014,19042,19070,19097,19125,19153,19181,19208,19236,19264,19293,19321, + 19349,19377,19406,19434,19462,19491,19519,19548,19577,19605,19634,19662,19691,19720,19749,19778, + 19807,19835,19864,19893,19922,19951,19981,20010,20040,20069,20098,20128,20157,20187,20216,20246, + 20276,20305,20335,20364,20394,20424,20454,20484,20514,20544,20574,20604,20634,20664,20695,20725, + 20756,20786,20816,20847,20877,20908,20939,20969,21000,21031,21062,21092,21123,21154,21185,21216, + 21247,21278,21309,21340,21371,21403,21434,21466,21497,21529,21560,21592,21623,21655,21687,21719, + 21751,21782,21814,21846,21878,21910,21943,21975,22007,22039,22072,22104,22136,22169,22202,22234, + 22267,22300,22333,22365,22398,22431,22464,22497,22530,22563,22596,22629,22662,22696,22729,22763, + 22796,22830,22863,22897,22930,22964,22998,23032,23066,23099,23133,23167,23201,23235,23270,23304, + 23338,23372,23407,23441,23475,23510,23545,23579,23614,23649,23684,23718,23753,23788,23823,23858, + 23894,23929,23964,23999,24034,24070,24105,24141,24176,24212,24247,24283,24318,24354,24390,24426, + 24462,24498,24534,24570,24606,24643,24679,24716,24752,24789,24825,24862,24898,24935,24972,25009, + 25046,25082,25119,25156,25193,25230,25268,25305,25342,25379,25417,25454,25491,25529,25567,25605, + 25643,25680,25718,25756,25794,25832,25871,25909,25947,25985,26024,26062,26100,26139,26178,26216, + 26255,26294,26333,26371,26410,26449,26488,26527,26567,26606,26645,26684,26723,26763,26802,26842, + 26882,26921,26961,27000,27040,27080,27121,27161,27201,27241,27282,27322,27362,27403,27443,27484, + 27525,27565,27606,27646,27687,27728,27769,27810,27852,27893,27934,27975,28016,28058,28099,28141, + 28183,28224,28266,28307,28349,28391,28433,28475,28518,28560,28602,28644,28686,28729,28772,28814, + 28857,28900,28943,28985,29028,29071,29114,29157,29201,29244,29287,29330,29373,29417,29461,29504, + 29548,29592,29636,29679,29723,29767,29812,29856,29900,29944,29989,30033,30077,30122,30167,30211, + 30256,30301,30346,30390,30435,30480,30526,30571,30617,30662,30707,30753,30798,30844,30890,30936, + 30982,31027,31073,31119,31165,31212,31258,31305,31351,31398,31444,31491,31537,31584,31631,31678, + 31725,31772,31819,31866,31913,31961,32008,32056,32104,32151,32199,32246,32294,32342,32390,32438, + 32487,32535,32583,32631,32679,32766,32777,32825,32874,32923,32972,33020,33069,33118,33168,33217, + 33267,33316,33365,33415,33464,33514,33564,33614,33664,33714,33764,33814,33864,33915,33965,34016, + 34067,34117,34168,34218,34269,34320,34371,34422,34474,34525,34576,34627,34678,34730,34782,34834, + 34886,34937,34989,35041,35093,35146,35198,35251,35303,35356,35408,35461,35513,35566,35619,35672, + 35725,35778,35831,35884,35937,35991,36045,36098,36152,36206,36260,36313,36367,36422,36476,36531, + 36585,36640,36694,36749,36803,36858,36913,36968,37023,37078,37133,37188,37243,37299,37355,37410, + 37466,37522,37578,37633,37689,37746,37802,37859,37915,37972,38028,38085,38141,38198,38255,38312, + 38369,38426,38483,38540,38597,38655,38713,38771,38829,38886,38944,39002, +]; diff --git a/crates/raw/src/vendor/mod.rs b/crates/raw/src/vendor/mod.rs index 0e4ca4143..492e396b0 100644 --- a/crates/raw/src/vendor/mod.rs +++ b/crates/raw/src/vendor/mod.rs @@ -2,6 +2,7 @@ pub mod arw; pub mod arw6; +mod arw6_curve; #[cfg(test)] pub(crate) mod arw6_testenc; mod arw_lens; diff --git a/crates/raw/tests/vendor_robust.rs b/crates/raw/tests/vendor_robust.rs index 81a751c87..cb79c87da 100644 --- a/crates/raw/tests/vendor_robust.rs +++ b/crates/raw/tests/vendor_robust.rs @@ -232,6 +232,7 @@ fn samples() -> Vec> { cfa_tiff("NIKON CORPORATION", 34713, 14, ByteOrder::Big), cfa_tiff("SONY", 32767, 12, ByteOrder::Little), cfa_tiff("SONY", 1, 14, ByteOrder::Little), + cfa_tiff("SONY", 32766, 14, ByteOrder::Little), pef(1), pef(65535), cfa_tiff("SAMSUNG", 1, 12, ByteOrder::Little), @@ -282,7 +283,7 @@ proptest! { #![proptest_config(ProptestConfig { cases: 2000, .. ProptestConfig::default() })] #[test] - fn mutated_vendor_files_never_panic(kind in 0usize..17, flips in proptest::collection::vec((any::(), any::()), 1..16), cut in any::()) { + fn mutated_vendor_files_never_panic(kind in 0usize..18, flips in proptest::collection::vec((any::(), any::()), 1..16), cut in any::()) { let mut data = samples().swap_remove(kind); let n = data.len(); for (i, v) in flips {