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

Add CodecOptions.disableChromaSubsampling #4057

Merged
merged 2 commits into from
Dec 11, 2023

Conversation

melissalinkert
Copy link
Member

Companion to ome/ome-codecs#29.

Note I do not see any actual difference between disableChromaSubsampling = false and disableChromaSubsampling = true with something like:

import loci.formats.MetadataTools;
import loci.formats.codec.CodecOptions;
import loci.formats.in.FakeReader;
import loci.formats.meta.IMetadata;
import loci.formats.out.TiffWriter;

public class Snippet {
  public static void main(String[] args) throws Exception {
    String fakeData = "test&sizeC=3&rgb=3.fake";
    IMetadata metadata = MetadataTools.createOMEXMLMetadata();
    try (FakeReader reader = new FakeReader()) {
      // read artificial 512x512 RGB image
      reader.setMetadataStore(metadata);
      reader.setId(fakeData);
      byte[] rgbPlane = reader.openBytes(0);

      // write JPEG in TIFF, using default settings (uses chroma subsampling)
      try (TiffWriter defaultWriter = new TiffWriter()) {
        defaultWriter.setMetadataRetrieve(metadata);
        defaultWriter.setInterleaved(reader.isInterleaved());
        defaultWriter.setId("default.tiff");
        defaultWriter.setCompression("JPEG");
        defaultWriter.saveBytes(0, rgbPlane);
      }

      // write JPEG in TIFF, explicitly disabling chroma subsampling
      try (TiffWriter noChromaWriter = new TiffWriter()) {
        noChromaWriter.setMetadataRetrieve(metadata);
        noChromaWriter.setInterleaved(reader.isInterleaved());

        CodecOptions options = CodecOptions.getDefaultOptions();
        options.disableChromaSubsampling = true;
        noChromaWriter.setCodecOptions(options);

        noChromaWriter.setId("no-chroma.tiff");
        noChromaWriter.setCompression("JPEG");

        noChromaWriter.saveBytes(0, rgbPlane);
      }
    }
  }
}

but as far as I can tell that's an issue with ome/ome-codecs#29 (review incoming).

@iwbh15
Copy link

iwbh15 commented Jul 21, 2023

In the structured fake data (where R = G = B) the effect of the disabled chroma subsampling is not huge.
Therefore I have use the image lena-std.tif for my test (available in the ImageJ example images zip archive).
(Of course you can use any other RGB tif image.)

I used the following modified snipped for the test:

import java.io.File;
import loci.formats.MetadataTools;
import loci.formats.codec.CodecOptions;
import loci.formats.in.FakeReader;
import loci.formats.in.TiffReader;
import loci.formats.meta.IMetadata;
import loci.formats.out.TiffWriter;

public class Snippet2 {

  public static void main(String[] args) throws Exception {
	    
    //String fakeData = "test&sizeC=3&rgb=3.fake";
    
    IMetadata metadata = MetadataTools.createOMEXMLMetadata();
	
    //try (FakeReader reader = new FakeReader()) {
    try (TiffReader reader = new TiffReader()) {
      reader.setMetadataStore(metadata);
	  
      // read artificial 512x512 RGB image
      //reader.setId(fakeData);
    	
      // read baboon.gif (available at e.g. https://imagej.nih.gov/ij/images/)
      reader.setId("lena-std.tif");
      
      int w = reader.getSizeX();
      int h = reader.getSizeY();
      byte[] buf = new byte[w*h*3];
      byte[] bufRGB = new byte[w*h*3];
      
      buf = reader.openBytes(0, buf, 0, 0, w, h);
      
      // re-ordered image buffer
      int idx;
      int offset1 = w*h;
      int offset2 = 2*w*h;
      for (int i=0; i<w*h; i++) {
    	  idx = 3*i;
    	  bufRGB[idx+2] = buf[i+offset2];
    	  bufRGB[idx+1] = buf[i+offset1];
    	  bufRGB[idx] = buf[i];
      }

      String compression = "JPEG";       // "Uncompressed"; // 
      
      // write JPEG in TIFF, using default settings (uses chroma subsampling)
      try (TiffWriter defaultWriter = new TiffWriter()) {
        defaultWriter.setMetadataRetrieve(metadata);
        defaultWriter.setInterleaved(true); //(reader.isInterleaved());
                
        // Image file has to be deleted, otherwise the new content will be append to the existing file
        String fName = "default.tif";
        File f = new File(fName);
        if (f.exists())
        	f.delete();
        
        defaultWriter.setId(fName);
        defaultWriter.setCompression(compression);
        
        defaultWriter.saveBytes(0, bufRGB);
      }
    
      // write JPEG in TIFF, explicitly disabling chroma subsampling
      try (TiffWriter noChromaWriter = new TiffWriter()) {
        noChromaWriter.setMetadataRetrieve(metadata);
        noChromaWriter.setInterleaved(true); //(reader.isInterleaved());

        CodecOptions options = CodecOptions.getDefaultOptions();

        options.disableChromaSubsampling = true;
        
        noChromaWriter.setCodecOptions(options);

        // Image file has to be deleted, otherwise the new content will be append to the existing file
        String fName = "no-chroma.tif";
        File f = new File(fName);
        if (f.exists())
        	f.delete();
        
        noChromaWriter.setId(fName);
        noChromaWriter.setCompression(compression);
      
        noChromaWriter.saveBytes(0, bufRGB);
      }
    }
  }
}

@dgault dgault added this to the 7.1.0 milestone Sep 4, 2023
@melissalinkert
Copy link
Member Author

Retested with the current state of this PR and ome/ome-codecs#29.

In all cases, both output files can be read by showinf and ImageMagick's display.

Build failures here are expected, and should go away when the ome-codecs version is bumped.

Copy link
Member

@dgault dgault left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested alongside the codecs PR. Looks good from my side. As soon as the codecs component has been bumped and builds are green then this should be ready to merge. I have held off bumping ome-codecs now as all of the components will need bumped as part of the sl4j-api updates.

@dgault dgault closed this Dec 11, 2023
@dgault dgault reopened this Dec 11, 2023
@dgault dgault merged commit 6d7692d into ome:develop Dec 11, 2023
19 of 34 checks passed
@melissalinkert melissalinkert deleted the disable-chroma-subsampling branch September 6, 2024 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants