Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tiff bitdepth ignored #3811

Open
3 tasks done
dnsbty opened this issue Sep 26, 2023 · 7 comments
Open
3 tasks done

Tiff bitdepth ignored #3811

dnsbty opened this issue Sep 26, 2023 · 7 comments
Labels

Comments

@dnsbty
Copy link
Contributor

dnsbty commented Sep 26, 2023

Possible bug

Is this a possible bug in a feature of sharp, unrelated to installation?

  • Running npm install sharp completes without error.
  • Running node -e "require('sharp')" completes without error.

If you cannot confirm both of these, please open an installation issue instead.

Are you using the latest version of sharp?

  • I am using the latest version of sharp as reported by npm view sharp dist-tags.latest.

If you cannot confirm this, please upgrade to the latest version and try again before opening an issue.

If you are using another package which depends on a version of sharp that is not the latest, please open an issue against that package instead.

What is the output of running npx envinfo --binaries --system --npmPackages=sharp --npmGlobalPackages=sharp?

System:
OS: macOS 13.5.2
CPU: (10) arm64 Apple M1 Max
Memory: 390.08 MB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.16.1 - ~/.asdf/installs/nodejs/18.16.1/bin/node
npm: 9.7.2 - ~/.asdf/plugins/nodejs/shims/npm
npmPackages:
sharp: ^0.32.6 => 0.32.6

What are the steps to reproduce?

await sharp("input.gif")
  .tiff({ bitdepth: 1 })
  .toFile("output.tif")

What is the expected behaviour?

When I run exiftool output.tif I would expect to see the following:

Bits Per Sample                 : 1

Instead I see this:

Bits Per Sample                 : 8 8 8

Please provide a minimal, standalone code sample, without other dependencies, that demonstrates this problem

Reproduction

Please provide sample image(s) that help explain this problem

This is the input gif I'm using:

input

And this is the tiff image that is outputted (compressed since Github doesn't allow tiff uploads):

output.tif.zip

@dnsbty dnsbty added the triage label Sep 26, 2023
@dnsbty
Copy link
Contributor Author

dnsbty commented Sep 26, 2023

In attempting to debug this myself, I tried dropping down to C++ to see if I could find anything. I created this script:

#include <vips/vips8>
using namespace vips;

int
main (int argc, char **argv)
{ 
  if (VIPS_INIT (argv[0])) 
    vips_error_exit (NULL);
  
  if (argc != 3)
    vips_error_exit ("usage: %s input-file output-file", argv[0]);

  VImage in = VImage::new_from_file (argv[1],
    VImage::option ()->set ("access", VIPS_ACCESS_SEQUENTIAL));
  
  in.tiffsave (argv[2], VImage::option ()->set ("bitdepth", 1));
  
  vips_shutdown ();
  
  return (0);
}

When I compile this:

g++ -g -Wall test.cc `pkg-config vips-cpp --cflags --libs` -o test

And then run it:

./test input.gif output.tif

I get this warning:

(process:60900): VIPS-WARNING **: 23:48:04.401: can only set bitdepth for 1-band uchar and 3-band float lab -- disabling bitdepth

I'm guessing this warning is being suppressed by sharp, and is probably the root of the issue. I'm having a hard time figuring out what this actually means though. Any pointers would be greatly appreciated.

@lovell
Copy link
Owner

lovell commented Sep 27, 2023

The addition of .removeAlpha().toColourspace('b-w') to a pipeline will reduce the input to a single, greyscale band suitable for use with a bitdepth of 1.

https://sharp.pixelplumbing.com/api-channel#removealpha
https://sharp.pixelplumbing.com/api-colour#tocolourspace

sharp supports the NODE_DEBUG feature of Node.js to view warnings, i.e. set the NODE_DEBUG=sharp environment variable. Perhaps this should be an error condition rather than a warning?

I think the miniswhite setting will support an optional alpha channel too. The underlying logic in libvips can be seen at https://github.com/libvips/libvips/blob/0819eccda6abe097c5da16edf8d028c7c0e6b595/libvips/foreign/vips2tiff.c#L1446-L1476

See also #3486 #3655

@dnsbty
Copy link
Contributor Author

dnsbty commented Sep 27, 2023

Thank you very much for writing that up. I'm not sure why those other issues didn't turn up when I searched. The NODE_DEBUG tip was especially helpful.

With that I was able to build up a working pipeline, but I think I found an incompatibility. When using .withMetadata({ density: 200 }) as recommended in the docs when working with inches, the bitdepth is ignored once again with the following warnings showing up when using the NODE_DEBUG environment variable:

SHARP 87527: profile incompatible with image
SHARP 87527: can only set bitdepth for 1-band uchar and 3-band float lab -- disabling bitdepth

This is the code I used. I've also updated the reproduction repository

await sharp(inputFile)
  .removeAlpha()
  .toColourspace('b-w')
  .withMetadata({ density: 200 })
  .tiff({ bitdepth: 1, compression: "lzw", predictor: "none" })
  .toFile(outputFile)

@dnsbty
Copy link
Contributor Author

dnsbty commented Sep 27, 2023

I should probably note that this has an easy workaround by providing the xres and yres options (converted from inches to millimeters) to the tiff function, but I thought it might be worth mentioning.

@lovell
Copy link
Owner

lovell commented Nov 22, 2023

If you still need help here, I do intend to revisit this issue once v0.33.0 is made available. There are a number of metadata-related changes in libvips v8.15.0 that we're about to take advantage of in sharp so it might all "just work" ™️ .

@lovell
Copy link
Owner

lovell commented May 16, 2024

@dnsbty Were you able to make any progress with this?

@dnsbty
Copy link
Contributor Author

dnsbty commented May 16, 2024

Because of the xres + yres workaround that I found, I didn't really need the fix anymore, so I haven't looked into it anymore since then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants