From 04e7f58cea2c1986943a12a5030c7f5cf77dc001 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 2 Nov 2024 13:03:58 +0000 Subject: [PATCH] Ensure background metadata can be parsed #4090 --- docs/api-input.md | 2 +- docs/changelog.md | 3 +++ lib/index.d.ts | 4 ++-- lib/input.js | 2 +- src/metadata.cc | 7 ++++--- test/fixtures/bgbn4a08.png | Bin 0 -> 140 bytes test/fixtures/bggn4a16.png | Bin 0 -> 2220 bytes test/fixtures/index.js | 2 ++ test/unit/metadata.js | 42 +++++++++++++++++++++++++++++++++++++ 9 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 test/fixtures/bgbn4a08.png create mode 100644 test/fixtures/bggn4a16.png diff --git a/docs/api-input.md b/docs/api-input.md index 7e7dbfb9..eaf00e23 100644 --- a/docs/api-input.md +++ b/docs/api-input.md @@ -31,7 +31,7 @@ A `Promise` is returned when `callback` is not provided. - `pagePrimary`: Number of the primary page in a HEIF image - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide - `subifds`: Number of Sub Image File Directories in an OME-TIFF image -- `background`: Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value +- `background`: Default background colour, if present, for PNG (bKGD) and GIF images - `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC) - `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present - `hasProfile`: Boolean indicating the presence of an embedded ICC profile diff --git a/docs/changelog.md b/docs/changelog.md index 01446f9c..261b3ec5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -10,6 +10,9 @@ Requires libvips v8.16.0-rc2 * Expose WebP `smartDeblock` output option. +* Ensure `background` metadata can be parsed by `color` package. + [#4090](https://github.com/lovell/sharp/issues/4090) + * TypeScript: Ensure channel counts use the correct range. [#4197](https://github.com/lovell/sharp/pull/4197) [@DavidVaness](https://github.com/DavidVaness) diff --git a/lib/index.d.ts b/lib/index.d.ts index 12816b2d..695fd544 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -1106,8 +1106,8 @@ declare namespace sharp { tifftagPhotoshop?: Buffer | undefined; /** The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC) */ compression?: 'av1' | 'hevc'; - /** Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value */ - background?: { r: number; g: number; b: number } | number; + /** Default background colour, if present, for PNG (bKGD) and GIF images */ + background?: { r: number; g: number; b: number } | { gray: number }; /** Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide */ levels?: LevelMetadata[] | undefined; /** Number of Sub Image File Directories in an OME-TIFF image */ diff --git a/lib/input.js b/lib/input.js index 9760de52..3a1562d4 100644 --- a/lib/input.js +++ b/lib/input.js @@ -443,7 +443,7 @@ function _isStreamInput () { * - `pagePrimary`: Number of the primary page in a HEIF image * - `levels`: Details of each level in a multi-level image provided as an array of objects, requires libvips compiled with support for OpenSlide * - `subifds`: Number of Sub Image File Directories in an OME-TIFF image - * - `background`: Default background colour, if present, for PNG (bKGD) and GIF images, either an RGB Object or a single greyscale value + * - `background`: Default background colour, if present, for PNG (bKGD) and GIF images * - `compression`: The encoder used to compress an HEIF file, `av1` (AVIF) or `hevc` (HEIC) * - `resolutionUnit`: The unit of resolution (density), either `inch` or `cm`, if present * - `hasProfile`: Boolean indicating the presence of an embedded ICC profile diff --git a/src/metadata.cc b/src/metadata.cc index 8be08294..2c1dfc79 100644 --- a/src/metadata.cc +++ b/src/metadata.cc @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -226,15 +227,15 @@ class MetadataWorker : public Napi::AsyncWorker { info.Set("subifds", baton->subifds); } if (!baton->background.empty()) { + Napi::Object background = Napi::Object::New(env); if (baton->background.size() == 3) { - Napi::Object background = Napi::Object::New(env); background.Set("r", baton->background[0]); background.Set("g", baton->background[1]); background.Set("b", baton->background[2]); - info.Set("background", background); } else { - info.Set("background", baton->background[0]); + background.Set("gray", round(baton->background[0] * 100 / 255)); } + info.Set("background", background); } info.Set("hasProfile", baton->hasProfile); info.Set("hasAlpha", baton->hasAlpha); diff --git a/test/fixtures/bgbn4a08.png b/test/fixtures/bgbn4a08.png new file mode 100644 index 0000000000000000000000000000000000000000..7cbefc3bff08a9d91666d6b0f8b5cb1c896b7987 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtq=#3k+XOiwE+VlDyqr z7#LRdDjNZLrk*a2Ar*6y|C~Q?fU$K>hKZrl9G&};8q7NOZTlD(CmKkxg%~E72)G|^ k&|>Rhdz2v&aF~JNzLrAmk=Ly!fCeyly85}Sb4q9e08Xzba{vGU literal 0 HcmV?d00001 diff --git a/test/fixtures/bggn4a16.png b/test/fixtures/bggn4a16.png new file mode 100644 index 0000000000000000000000000000000000000000..13fd85ba193369dbd84a0dc07f73d3340485fa6a GIT binary patch literal 2220 zcmV;d2vhfoP))?Z7@1GU()&K|^FGh>0bpfeScg5Q zVAO&a&cd+)IQ~b-4#C+!!^K_j-evgc3Haw<;qG2ozb?Ob_sZEvPslSDcgg=`hvYMk z4ajGXTJjykx_l>qW@VvfTe+?o@D-uE0$LFQyCHB0^d^MfhURr>7s1nDV+1ouL#<%toKz$mb>Sfw9$NoD zuRm}G@SOqQg}(RtLucx>YCvShv8{A1qgh$$yvv2EVP$$}{d$u=YBv+<<$> zz}W)TgRndc{U;qe;zHjHm@&lxtq9sLq;uaKEX`V3-=m=IgJ2Bwy%W850@T-__AjWmVEHyI&BE5vnjOu6RR!~1=)I3XU^n=GCa`N` z;CmDn3z4kv4ER5Q;0hQe2%muUIyBz`Zv{55N&()8oUQv|^#s&Q;Jg6KM`6i?#R3eZ z9lJjPkqnrxK)47!^9q5$AqbRZ=Ke3GbKe=Lm{wMcLvRp`K?o0mH3*GCXzzi}pcK$9 zL8Am~C8+-$oDwXT;6Ej(lp$8H*;_w@XaM?lK=@nenE~T33IV+d`W_*ieo zO65pa(?Hjuw-+o6To+m`=yarjR!h$6b*NThX$dM7D3xI_?${64p??Cb3WR?RJ!vqC z5Sms9gx-eGE@69UQDz=okTDWGOUB@SPF0`qa$JzcYho`!)75RHPl z0=;Pn{Q>l6Aovdm6v2NV0Z)VWYa%kO4`tQX>q0oo64?7{V3c7l9?3=$Fr0u!LJC;C z2LHYdbGKn{*|B#%3EM1)rol9!rw*Ys=wlH0IryIke-SiKA+Rw58`nhPywkGh&9{W@ zt}8R&vQ0XVB;e|8D;wVrKRqf1e0~nDz7GcyHG5YXVy7T_7s5ke7@&U#!B@e55VYf< z-GuHL=)R>8=sXJ@L*#Yiu!xMeBCFPF3E|vPfqggu@%?b_d?Y(QE(M%B4==yu*pHWC zpbXYD7_*=+Kp+7A1<=yay<3UhFGc=+?4Mpnn7YQ=m5Rv)f6IrzbiJJX*S!NE>`GEvny$wzr zcK+&nYq$+UdC*^jKvS(@O0A(|ON?rTRG9FTrJfLDsa8c^7d{q|*;{t(U5f4cH&VdB zKIzm|r1R#46x<$$Mgv?E+`KZQHzT}wcx9w z?OlokT3+@%loz&}1(|uXAf0#8(okm}W>PYu^r);W8@8JR^Rt9T!*Y8c_vY7KIBmWzUV9!uD`ZX5KDJ=baoZPeI3qP6{?` z`0=l1jx86($c$r0QtHO?uFCB*D!mpZ!v%_xWV+QwwyP)w_>!XS{*)+OFe!U(B!%s* zl+4^qO6Qw1;G|$Pt2kg~YZ)socQrF6H=--;jDE40000 { + const data = await sharp(fixtures.inputPng8BitGreyBackground).metadata(); + assert.deepStrictEqual(data, { + background: { + gray: 0 + }, + bitsPerSample: 8, + channels: 2, + density: 72, + depth: 'uchar', + format: 'png', + hasAlpha: true, + hasProfile: false, + height: 32, + isPalette: false, + isProgressive: false, + space: 'b-w', + width: 32 + }); + }); + + it('PNG with greyscale bKGD chunk - 16 bit', async () => { + const data = await sharp(fixtures.inputPng16BitGreyBackground).metadata(); + assert.deepStrictEqual(data, { + background: { + gray: 67 + }, + bitsPerSample: 16, + channels: 2, + density: 72, + depth: 'ushort', + format: 'png', + hasAlpha: true, + hasProfile: false, + height: 32, + isPalette: false, + isProgressive: false, + space: 'grey16', + width: 32 + }); + }); + it('WebP', function (done) { sharp(fixtures.inputWebP).metadata(function (err, metadata) { if (err) throw err;