/// <summary> /// Get static cached instance of <see cref="ModifiedHuffmanCompressionAlgorithm"/>. /// </summary> /// <param name="fillOrder">The FillOrder tag specified in the image file directory.</param> /// <returns>A cached instance of <see cref="ModifiedHuffmanCompressionAlgorithm"/>.</returns> public static ModifiedHuffmanCompressionAlgorithm GetSharedInstance(TiffFillOrder fillOrder) { if (fillOrder != TiffFillOrder.LowerOrderBitsFirst) { return(HigherOrderBitsFirstInstance); } return(LowerOrderBitsFirstInstance); }
/// <summary> /// Get static cached instance of <see cref="CcittGroup4Compression"/>. /// </summary> /// <param name="fillOrder">The FillOrder tag specified in the image file directory.</param> /// <returns>A cached instance of <see cref="CcittGroup4Compression"/>.</returns> public static CcittGroup4Compression GetSharedInstance(TiffFillOrder fillOrder) { if (fillOrder != TiffFillOrder.LowerOrderBitsFirst) { return(HigherOrderBitsFirstInstance); } return(LowerOrderBitsFirstInstance); }
/// <summary> /// Initializes a new instance of the <see cref="ModifiedHuffmanTiffCompression" /> class. /// </summary> /// <param name="allocator">The memory allocator.</param> /// <param name="fillOrder">The logical order of bits within a byte.</param> /// <param name="width">The image width.</param> /// <param name="bitsPerPixel">The number of bits per pixel.</param> /// <param name="photometricInterpretation">The photometric interpretation.</param> public ModifiedHuffmanTiffCompression(MemoryAllocator allocator, TiffFillOrder fillOrder, int width, int bitsPerPixel, TiffPhotometricInterpretation photometricInterpretation) : base(allocator, width, bitsPerPixel) { this.FillOrder = fillOrder; bool isWhiteZero = photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero; this.whiteValue = (byte)(isWhiteZero ? 0 : 1); this.blackValue = (byte)(isWhiteZero ? 1 : 0); }
public static TiffBaseDecompressor Create( Configuration configuration, TiffDecoderCompressionType method, MemoryAllocator allocator, TiffPhotometricInterpretation photometricInterpretation, int width, int bitsPerPixel, TiffColorType colorType, TiffPredictor predictor, FaxCompressionOptions faxOptions, byte[] jpegTables, TiffFillOrder fillOrder, ByteOrder byteOrder) { switch (method) { case TiffDecoderCompressionType.None: DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return(new NoneTiffCompression(allocator, width, bitsPerPixel)); case TiffDecoderCompressionType.PackBits: DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return(new PackBitsTiffCompression(allocator, width, bitsPerPixel)); case TiffDecoderCompressionType.Deflate: DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return(new DeflateTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian)); case TiffDecoderCompressionType.Lzw: DebugGuard.IsTrue(faxOptions == FaxCompressionOptions.None, "No fax compression options are expected"); return(new LzwTiffCompression(allocator, width, bitsPerPixel, colorType, predictor, byteOrder == ByteOrder.BigEndian)); case TiffDecoderCompressionType.T4: DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return(new T4TiffCompression(allocator, fillOrder, width, bitsPerPixel, faxOptions, photometricInterpretation)); case TiffDecoderCompressionType.T6: DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return(new T6TiffCompression(allocator, fillOrder, width, bitsPerPixel, photometricInterpretation)); case TiffDecoderCompressionType.HuffmanRle: DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return(new ModifiedHuffmanTiffCompression(allocator, fillOrder, width, bitsPerPixel, photometricInterpretation)); case TiffDecoderCompressionType.Jpeg: DebugGuard.IsTrue(predictor == TiffPredictor.None, "Predictor should only be used with lzw or deflate compression"); return(new JpegTiffCompression(configuration, allocator, width, bitsPerPixel, jpegTables, photometricInterpretation)); default: throw TiffThrowHelper.NotSupportedDecompressor(nameof(method)); } }
/// <summary> /// Initialize the middleware with the specified bit count and fill order. /// </summary> /// <param name="bitCount">The bit count.</param> /// <param name="fillOrder">The FillOrder tag.</param> public TiffWhiteIsZeroAny32Interpreter(int bitCount, TiffFillOrder fillOrder = TiffFillOrder.HigherOrderBitsFirst) { if ((uint)bitCount > 32) { throw new ArgumentOutOfRangeException(nameof(bitCount)); } if (fillOrder == 0) { fillOrder = TiffFillOrder.HigherOrderBitsFirst; } _bitCount = bitCount; _fillOrder = fillOrder; }
/// <summary> /// Initialize the middleware with the specified bits per sample and fill order. /// </summary> /// <param name="bitsPerSample">The BitsPerSample flags.</param> /// <param name="fillOrder">The FillOrder tag.</param> public TiffChunkyRgbAny888Interpreter(TiffValueCollection <ushort> bitsPerSample, TiffFillOrder fillOrder = TiffFillOrder.HigherOrderBitsFirst) { if (bitsPerSample.Count != 3) { throw new ArgumentOutOfRangeException(nameof(bitsPerSample)); } if ((uint)bitsPerSample[0] > 8 || (uint)bitsPerSample[1] > 8 || (uint)bitsPerSample[2] > 8) { throw new ArgumentOutOfRangeException(nameof(bitsPerSample)); } if (fillOrder == 0) { fillOrder = TiffFillOrder.HigherOrderBitsFirst; } _bitsPerSample = bitsPerSample; _fillOrder = fillOrder; }
/// <summary> /// Initializes a new instance of the <see cref="T4TiffCompression" /> class. /// </summary> /// <param name="allocator">The memory allocator.</param> /// <param name="fillOrder">The logical order of bits within a byte.</param> /// <param name="width">The image width.</param> /// <param name="bitsPerPixel">The number of bits per pixel.</param> /// <param name="faxOptions">Fax compression options.</param> /// <param name="photometricInterpretation">The photometric interpretation.</param> public T4TiffCompression( MemoryAllocator allocator, TiffFillOrder fillOrder, int width, int bitsPerPixel, FaxCompressionOptions faxOptions, TiffPhotometricInterpretation photometricInterpretation) : base(allocator, width, bitsPerPixel) { this.faxCompressionOptions = faxOptions; this.FillOrder = fillOrder; this.width = width; bool isWhiteZero = photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero; this.whiteValue = (byte)(isWhiteZero ? 0 : 1); this.blackValue = (byte)(isWhiteZero ? 1 : 0); }
/// <summary> /// Initialize the middleware with the specified bit count and fill order. /// </summary> /// <param name="colorMap">The color map.</param> /// <param name="bitCount">The bit count.</param> /// <param name="fillOrder">The FillOrder tag.</param> public TiffPaletteColorAny8Interpreter(ushort[] colorMap, int bitCount, TiffFillOrder fillOrder = TiffFillOrder.HigherOrderBitsFirst) { if ((uint)bitCount > 32) { throw new ArgumentOutOfRangeException(nameof(bitCount)); } if (fillOrder == 0) { fillOrder = TiffFillOrder.HigherOrderBitsFirst; } _bitCount = bitCount; _fillOrder = fillOrder; _colorMap = colorMap ?? throw new ArgumentNullException(nameof(colorMap)); if (_colorMap.Length < 3 * SingleColorCount) { throw new ArgumentException($"Color map requires {3 * SingleColorCount} elements.", nameof(colorMap)); } }
/// <summary> /// Initialize the middleware. /// </summary> /// <param name="isAlphaAssociated">Whether the alpha channel is associated.</param> /// <param name="undoColorPreMultiplying">Whether to undo color pre-multiplying.</param> /// <param name="bitsPerSample">The BitsPerSample flags.</param> /// <param name="fillOrder">The FillOrder tag.</param> public TiffChunkyRgbaAny8888Interpreter(bool isAlphaAssociated, bool undoColorPreMultiplying, TiffValueCollection <ushort> bitsPerSample, TiffFillOrder fillOrder = TiffFillOrder.HigherOrderBitsFirst) { _isAlphaAssociated = isAlphaAssociated; _undoColorPreMultiplying = undoColorPreMultiplying; if (bitsPerSample.Count != 4) { throw new ArgumentOutOfRangeException(nameof(bitsPerSample)); } if ((uint)bitsPerSample[0] > 8 || (uint)bitsPerSample[1] > 8 || (uint)bitsPerSample[2] > 8 || (uint)bitsPerSample[3] > 8) { throw new ArgumentOutOfRangeException(nameof(bitsPerSample)); } if (fillOrder == 0) { fillOrder = TiffFillOrder.HigherOrderBitsFirst; } _bitsPerSample = bitsPerSample; _fillOrder = fillOrder; }
/// <summary> /// Initializes a new instance of the <see cref="T4BitReader" /> class. /// </summary> /// <param name="input">The compressed input stream.</param> /// <param name="fillOrder">The logical order of bits within a byte.</param> /// <param name="bytesToRead">The number of bytes to read from the stream.</param> /// <param name="allocator">The memory allocator.</param> /// <param name="eolPadding">Indicates, if fill bits have been added as necessary before EOL codes such that EOL always ends on a byte boundary. Defaults to false.</param> public T4BitReader(Stream input, TiffFillOrder fillOrder, int bytesToRead, MemoryAllocator allocator, bool eolPadding = false) { this.fillOrder = fillOrder; this.Data = allocator.Allocate <byte>(bytesToRead); this.ReadImageDataFromStream(input, bytesToRead); this.DataLength = bytesToRead; this.BitsRead = 0; this.Value = 0; this.CurValueBitsRead = 0; this.Position = 0; this.IsWhiteRun = true; this.isFirstScanLine = true; this.isStartOfRow = true; this.terminationCodeFound = false; this.RunLength = 0; this.eolPadding = eolPadding; if (this.eolPadding) { this.maxCodeLength = 24; } }
/// <summary> /// Initializes a new instance of the <see cref="ModifiedHuffmanBitReader"/> class. /// </summary> /// <param name="input">The compressed input stream.</param> /// <param name="fillOrder">The logical order of bits within a byte.</param> /// <param name="bytesToRead">The number of bytes to read from the stream.</param> /// <param name="allocator">The memory allocator.</param> public ModifiedHuffmanBitReader(Stream input, TiffFillOrder fillOrder, int bytesToRead, MemoryAllocator allocator) : base(input, fillOrder, bytesToRead, allocator) { }
/// <summary> /// Initialize the middleware with the specified fill order. /// </summary> /// <param name="fillOrder">The FillOrder tag.</param> public TiffWhiteIsZero1Interpreter(TiffFillOrder fillOrder) { _shouldReverseBits = fillOrder == TiffFillOrder.LowerOrderBitsFirst; }
public void GetFillOrder_ReturnsValue(ByteOrder byteOrder, TiffType type, int?data, TiffFillOrder expectedResult) { var ifd = TiffIfdBuilder.GenerateIfd(TiffTags.FillOrder, type, data, byteOrder).Ifd; var result = ifd.GetFillOrder(byteOrder); Assert.Equal(expectedResult, result); }
/// <summary> /// Get static cached instance of <see cref="CcittGroup3OneDimensionalCompressionAlgorithm"/>. /// </summary> /// <param name="fillOrder">The FillOrder tag specified in the image file directory.</param> /// <returns>A cached instance of <see cref="CcittGroup3OneDimensionalCompressionAlgorithm"/>.</returns> public static CcittGroup3OneDimensionalCompressionAlgorithm GetSharedInstance(TiffFillOrder fillOrder) { if (fillOrder != TiffFillOrder.LowerOrderBitsFirst) { return(HigherOrderBitsFirstInstance); } return(LowerOrderBitsFirstInstance); }
/// <summary> /// Initialize the middleware with the specified fill order. /// </summary> /// <param name="fillOrder">The FillOrder tag.</param> public TiffTransparencyMask1Interpreter(TiffFillOrder fillOrder) { _shouldReverseBits = fillOrder == TiffFillOrder.LowerOrderBitsFirst; }
/// <summary> /// Determines the TIFF compression and color types, and reads any associated parameters. /// </summary> /// <param name="options">The options.</param> /// <param name="exifProfile">The exif profile of the frame to decode.</param> /// <param name="frameMetadata">The IFD entries container to read the image format information for current frame.</param> public static void VerifyAndParse(this TiffDecoderCore options, ExifProfile exifProfile, TiffFrameMetadata frameMetadata) { if (exifProfile.GetValueInternal(ExifTag.TileOffsets) is not null || exifProfile.GetValueInternal(ExifTag.TileByteCounts) is not null) { TiffThrowHelper.ThrowNotSupported("Tiled images are not supported."); } if (exifProfile.GetValueInternal(ExifTag.ExtraSamples) is not null) { TiffThrowHelper.ThrowNotSupported("ExtraSamples is not supported."); } TiffFillOrder fillOrder = (TiffFillOrder?)exifProfile.GetValue(ExifTag.FillOrder)?.Value ?? TiffFillOrder.MostSignificantBitFirst; if (fillOrder == TiffFillOrder.LeastSignificantBitFirst && frameMetadata.BitsPerPixel != TiffBitsPerPixel.Bit1) { TiffThrowHelper.ThrowNotSupported("The lower-order bits of the byte FillOrder is only supported in combination with 1bit per pixel bicolor tiff's."); } if (frameMetadata.Predictor == TiffPredictor.FloatingPoint) { TiffThrowHelper.ThrowNotSupported("TIFF images with FloatingPoint horizontal predictor are not supported."); } TiffSampleFormat[] sampleFormats = exifProfile.GetValue(ExifTag.SampleFormat)?.Value?.Select(a => (TiffSampleFormat)a).ToArray(); TiffSampleFormat? sampleFormat = null; if (sampleFormats != null) { sampleFormat = sampleFormats[0]; foreach (TiffSampleFormat format in sampleFormats) { if (format != TiffSampleFormat.UnsignedInteger && format != TiffSampleFormat.Float) { TiffThrowHelper.ThrowNotSupported("ImageSharp only supports the UnsignedInteger and Float SampleFormat."); } } } ushort[] ycbcrSubSampling = exifProfile.GetValue(ExifTag.YCbCrSubsampling)?.Value; if (ycbcrSubSampling != null && ycbcrSubSampling.Length != 2) { TiffThrowHelper.ThrowImageFormatException("Invalid YCbCrSubsampling, expected 2 values."); } if (ycbcrSubSampling != null && ycbcrSubSampling[1] > ycbcrSubSampling[0]) { TiffThrowHelper.ThrowImageFormatException("ChromaSubsampleVert shall always be less than or equal to ChromaSubsampleHoriz."); } if (exifProfile.GetValue(ExifTag.StripRowCounts)?.Value != null) { TiffThrowHelper.ThrowNotSupported("Variable-sized strips are not supported."); } VerifyRequiredFieldsArePresent(exifProfile, frameMetadata); options.PlanarConfiguration = (TiffPlanarConfiguration?)exifProfile.GetValue(ExifTag.PlanarConfiguration)?.Value ?? DefaultPlanarConfiguration; options.Predictor = frameMetadata.Predictor ?? TiffPredictor.None; options.PhotometricInterpretation = frameMetadata.PhotometricInterpretation ?? TiffPhotometricInterpretation.Rgb; options.SampleFormat = sampleFormat ?? TiffSampleFormat.UnsignedInteger; options.BitsPerPixel = frameMetadata.BitsPerPixel != null ? (int)frameMetadata.BitsPerPixel.Value : (int)TiffBitsPerPixel.Bit24; options.BitsPerSample = frameMetadata.BitsPerSample ?? new TiffBitsPerSample(0, 0, 0); options.ReferenceBlackAndWhite = exifProfile.GetValue(ExifTag.ReferenceBlackWhite)?.Value; options.YcbcrCoefficients = exifProfile.GetValue(ExifTag.YCbCrCoefficients)?.Value; options.YcbcrSubSampling = exifProfile.GetValue(ExifTag.YCbCrSubsampling)?.Value; options.FillOrder = fillOrder; options.JpegTables = exifProfile.GetValue(ExifTag.JPEGTables)?.Value; options.ParseColorType(exifProfile); options.ParseCompression(frameMetadata.Compression, exifProfile); }