/// <summary> /// Parses the given Exif profile to populate the properties of the tiff frame meta data. /// </summary> /// <param name="meta">The tiff frame meta data.</param> /// <param name="profile">The Exif profile containing tiff frame directory tags.</param> internal static void Parse(TiffFrameMetadata meta, ExifProfile profile) { if (profile != null) { if (TiffBitsPerSample.TryParse(profile.GetValue(ExifTag.BitsPerSample)?.Value, out TiffBitsPerSample bitsPerSample)) { meta.BitsPerSample = bitsPerSample; } meta.BitsPerPixel = meta.BitsPerSample?.BitsPerPixel(); meta.Compression = (TiffCompression?)profile.GetValue(ExifTag.Compression)?.Value; meta.PhotometricInterpretation = (TiffPhotometricInterpretation?)profile.GetValue(ExifTag.PhotometricInterpretation)?.Value; meta.Predictor = (TiffPredictor?)profile.GetValue(ExifTag.Predictor)?.Value; profile.RemoveValue(ExifTag.BitsPerSample); profile.RemoveValue(ExifTag.Compression); profile.RemoveValue(ExifTag.PhotometricInterpretation); profile.RemoveValue(ExifTag.Predictor); } }
private static void ParseColorType(this TiffDecoderCore options, ExifProfile exifProfile) { switch (options.PhotometricInterpretation) { case TiffPhotometricInterpretation.WhiteIsZero: { if (options.BitsPerSample.Channels != 1) { TiffThrowHelper.ThrowNotSupported("The number of samples in the TIFF BitsPerSample entry is not supported."); } ushort bitsPerChannel = options.BitsPerSample.Channel0; if (bitsPerChannel > 32) { TiffThrowHelper.ThrowNotSupported("Bits per sample is not supported."); } switch (bitsPerChannel) { case 32: { if (options.SampleFormat == TiffSampleFormat.Float) { options.ColorType = TiffColorType.WhiteIsZero32Float; return; } options.ColorType = TiffColorType.WhiteIsZero32; break; } case 24: { options.ColorType = TiffColorType.WhiteIsZero24; break; } case 16: { options.ColorType = TiffColorType.WhiteIsZero16; break; } case 8: { options.ColorType = TiffColorType.WhiteIsZero8; break; } case 4: { options.ColorType = TiffColorType.WhiteIsZero4; break; } case 1: { options.ColorType = TiffColorType.WhiteIsZero1; break; } default: { options.ColorType = TiffColorType.WhiteIsZero; break; } } break; } case TiffPhotometricInterpretation.BlackIsZero: { if (options.BitsPerSample.Channels != 1) { TiffThrowHelper.ThrowNotSupported("The number of samples in the TIFF BitsPerSample entry is not supported."); } ushort bitsPerChannel = options.BitsPerSample.Channel0; if (bitsPerChannel > 32) { TiffThrowHelper.ThrowNotSupported("Bits per sample is not supported."); } switch (bitsPerChannel) { case 32: { if (options.SampleFormat == TiffSampleFormat.Float) { options.ColorType = TiffColorType.BlackIsZero32Float; return; } options.ColorType = TiffColorType.BlackIsZero32; break; } case 24: { options.ColorType = TiffColorType.BlackIsZero24; break; } case 16: { options.ColorType = TiffColorType.BlackIsZero16; break; } case 8: { options.ColorType = TiffColorType.BlackIsZero8; break; } case 4: { options.ColorType = TiffColorType.BlackIsZero4; break; } case 1: { options.ColorType = TiffColorType.BlackIsZero1; break; } default: { options.ColorType = TiffColorType.BlackIsZero; break; } } break; } case TiffPhotometricInterpretation.Rgb: { TiffBitsPerSample bitsPerSample = options.BitsPerSample; if (bitsPerSample.Channels != 3) { TiffThrowHelper.ThrowNotSupported("The number of samples in the TIFF BitsPerSample entry is not supported."); } if (!(bitsPerSample.Channel0 == bitsPerSample.Channel1 && bitsPerSample.Channel1 == bitsPerSample.Channel2)) { TiffThrowHelper.ThrowNotSupported("Only BitsPerSample with equal bits per channel are supported."); } if (options.PlanarConfiguration == TiffPlanarConfiguration.Chunky) { ushort bitsPerChannel = options.BitsPerSample.Channel0; switch (bitsPerChannel) { case 32: if (options.SampleFormat == TiffSampleFormat.Float) { options.ColorType = TiffColorType.RgbFloat323232; return; } options.ColorType = TiffColorType.Rgb323232; break; case 24: options.ColorType = TiffColorType.Rgb242424; break; case 16: options.ColorType = TiffColorType.Rgb161616; break; case 14: options.ColorType = TiffColorType.Rgb141414; break; case 12: options.ColorType = TiffColorType.Rgb121212; break; case 10: options.ColorType = TiffColorType.Rgb101010; break; case 8: options.ColorType = TiffColorType.Rgb888; break; case 4: options.ColorType = TiffColorType.Rgb444; break; case 2: options.ColorType = TiffColorType.Rgb222; break; default: TiffThrowHelper.ThrowNotSupported("Bits per sample is not supported."); break; } } else { ushort bitsPerChannel = options.BitsPerSample.Channel0; switch (bitsPerChannel) { case 32: options.ColorType = TiffColorType.Rgb323232Planar; break; case 24: options.ColorType = TiffColorType.Rgb242424Planar; break; case 16: options.ColorType = TiffColorType.Rgb161616Planar; break; default: options.ColorType = TiffColorType.Rgb888Planar; break; } } break; } case TiffPhotometricInterpretation.PaletteColor: { options.ColorMap = exifProfile.GetValue(ExifTag.ColorMap)?.Value; if (options.ColorMap != null) { if (options.BitsPerSample.Channels != 1) { TiffThrowHelper.ThrowNotSupported("The number of samples in the TIFF BitsPerSample entry is not supported."); } options.ColorType = TiffColorType.PaletteColor; } else { TiffThrowHelper.ThrowNotSupported("The TIFF ColorMap entry is missing for a palette color image."); } break; } case TiffPhotometricInterpretation.YCbCr: { options.ColorMap = exifProfile.GetValue(ExifTag.ColorMap)?.Value; if (options.BitsPerSample.Channels != 3) { TiffThrowHelper.ThrowNotSupported("The number of samples in the TIFF BitsPerSample entry is not supported."); } ushort bitsPerChannel = options.BitsPerSample.Channel0; if (bitsPerChannel != 8) { TiffThrowHelper.ThrowNotSupported("Only 8 bits per channel is supported for YCbCr images."); } options.ColorType = options.PlanarConfiguration == TiffPlanarConfiguration.Chunky ? TiffColorType.YCbCr : TiffColorType.YCbCrPlanar; break; } default: { TiffThrowHelper.ThrowNotSupported($"The specified TIFF photometric interpretation is not supported: {options.PhotometricInterpretation}"); } break; } }