image-rs / image-tiff

TIFF decoding and encoding library in pure Rust
MIT License
107 stars 68 forks source link

FormatError(StripTileTagConflict) with minimal example trying to write an image #232

Open Ploppz opened 2 months ago

Ploppz commented 2 months ago

This is more of a request for support. Trying to use this library to create a tiff file and read it:

use tiff::decoder::Decoder;
use tiff::encoder::colortype::Gray8;
use tiff::tags::{PhotometricInterpretation, Tag};

const TIFF_PATH: &str = "a.tif";

fn main() {
    // Write
    // -----

    {
        let file = std::fs::OpenOptions::new()
            .write(true)
            .create(true)
            .append(false)
            .open(TIFF_PATH)
            .unwrap();
        let mut encoder = tiff::encoder::TiffEncoder::new(file).unwrap();

        {
            let mut directory = encoder.new_directory().unwrap();
            directory.write_tag(Tag::ImageWidth, 1u32).unwrap();
            directory.write_tag(Tag::ImageLength, 1u32).unwrap();
            directory
                .write_tag(
                    Tag::PhotometricInterpretation,
                    PhotometricInterpretation::BlackIsZero as u16,
                )
                .unwrap();
            // directory.write_tag(Tag::RowsPerStrip, 1_u32).unwrap();

            directory.finish().unwrap();
        }

        // Write image
        encoder.write_image::<Gray8>(1, 1, &[0u8; 1]).unwrap();
    }

    // Read
    // ----

    let tiff_file = std::fs::File::open(TIFF_PATH).unwrap();

    // Get TIFF file "Image Description" tag:
    let _ = Decoder::new(tiff_file).unwrap();
}

Error:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: FormatError(StripTileTagConflict)', src/main.rs:45:37

That's the last line trying to decode the tiff file. The Tiff file cannot be opened by other programs either.

What am I doing wrong in creation of the file? As you can see I tried RowsPerStrip to disambiguate the layout but it still gives the same error if you uncomment that line.

fintelia commented 2 months ago

Short answer is that write_image internally calls directory.finish() so you shouldn't call it yourself. The dimensions also get set in write_image though I think it is harmless to set them a second time. But really we should do an overhaul of the encoding API so that stuff like that is more obvious...

Ploppz commented 2 months ago

Deleting the directory.finish() line, I still get the same error.

Deleting the lines setting ImageWidth and ImageHeight, I get error FormatError(RequiredTagNotFound(ImageWidth)).

fintelia commented 1 month ago

I don't have time to look into this right now, but this is how the image crate uses the TiffEncoder: https://github.com/image-rs/image/blob/d48c6a6ff310b356018ffd6b5daff0d73587c039/src/codecs/tiff.rs#L342