From cdef6624ac7ab7394460faab3477bad0f8353500 Mon Sep 17 00:00:00 2001 From: Sawraz Date: Fri, 17 Jul 2026 15:14:56 +0600 Subject: [PATCH 1/2] update nuspec for August Release --- NuGet/IronSoftware.Drawing.nuspec | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/NuGet/IronSoftware.Drawing.nuspec b/NuGet/IronSoftware.Drawing.nuspec index 611816a..0e64b70 100644 --- a/NuGet/IronSoftware.Drawing.nuspec +++ b/NuGet/IronSoftware.Drawing.nuspec @@ -42,12 +42,11 @@ For general support and technical inquiries, please email us at: support@ironsof IronSoftware.System.Drawing is an open-source solution for .NET developers to replace System.Drawing.Common with a universal and flexible library. Features -- Added support for creating multi-page TIFFs while preserving per-page dimensions, orientation, and resolution +- Added support for loading TIFF and BigTIFF files larger than 2 GB using a streaming loader, enabling page-by-page decoding without loading the entire file into memory Enhancements -- Added support for converting AnyBitmap images to 8, 24, or 32 bits per pixel +- AnyBitmap now preserves the original source color depth (BitsPerPixel) across derived operations, including frame extraction, cloning, rotation, redaction, and resizing Bug Fixes -- Fixed an issue where AnyBitmap.BitsPerPixel reported incorrect color depths for TIFF images -- Fixed issues affecting multi-page TIFF generation, including incorrect resolution metadata and corrupted output for certain RGB image formats +- Fixed an issue where derived AnyBitmap operations incorrectly reported a decoded 32bpp color depth instead of the original source pixel depth Copyright © Iron Software 2022-2026 Images, Bitmap, SkiaSharp, SixLabors, BitMiracle, Maui, SVG, TIFF, TIF, GIF, JPEG, PNG, Color, Rectangle, Drawing, C#, VB.NET, ASPX, create, render, generate, standard, netstandard2.0, core, netcore From 00d8a351af10598435ad19f9ae5128223a2bbdf2 Mon Sep 17 00:00:00 2001 From: Sawraz Date: Wed, 29 Jul 2026 09:08:05 +0600 Subject: [PATCH 2/2] update(DW-39): Fix FromTiffFile preserving original TIFF bits-per-pixel metadata --- .../UnitTests/AnyBitmapFunctionality.cs | 15 ++++++++++++++ .../IronSoftware.Drawing.Common/AnyBitmap.cs | 20 ++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common.Tests/UnitTests/AnyBitmapFunctionality.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common.Tests/UnitTests/AnyBitmapFunctionality.cs index 979f520..88e2a8c 100644 --- a/IronSoftware.Drawing/IronSoftware.Drawing.Common.Tests/UnitTests/AnyBitmapFunctionality.cs +++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common.Tests/UnitTests/AnyBitmapFunctionality.cs @@ -650,6 +650,21 @@ public void FromTiffFile_MissingFile_ThrowsFileNotFound() act.Should().Throw(); } + [TheoryWithAutomaticDisplayName] + [InlineData("example.tif")] // 24 bpp + [InlineData("test_dw_10.tif")] // 1 bpp, multi-page + [InlineData("multiframe.tiff")] // 16 bpp + public void FromTiffFile_BitsPerPixel_MatchesFromFile(string fileName) + { + string tiffPath = GetRelativeFilePath(fileName); + + int expected = AnyBitmap.FromFile(tiffPath).BitsPerPixel; + int streamed = AnyBitmap.FromTiffFile(tiffPath).BitsPerPixel; + + streamed.Should().Be(expected, + $"FromTiffFile should report the source color depth for '{fileName}', matching FromFile"); + } + [FactWithAutomaticDisplayName] public void Create_Multi_page_Tiff() { diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs index 70c4dc3..655c647 100644 --- a/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs +++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs @@ -963,7 +963,8 @@ public static AnyBitmap FromTiffFile(string file) } AnyBitmap bitmap = new(); - bitmap.LoadLargeTiffFromFile(file); + // Preserve the source color depth so BitsPerPixel reports it, matching FromFile. + bitmap.LoadLargeTiffFromFile(file, preserveOriginalFormat: true); return bitmap; } @@ -3270,7 +3271,7 @@ private void LoadImageFromFile(string file, bool preserveOriginalFormat) if (IsTiffFile(file)) { // Stream the TIFF page-by-page; never materialise the whole file. - LoadLargeTiffFromFile(file); + LoadLargeTiffFromFile(file, preserveOriginalFormat); return; } @@ -3315,7 +3316,12 @@ private static bool IsTiffFile(string file) /// time through the underlying , so the entire file /// is never allocated as one array, enabling TIFF files larger than 2 GB. /// - private void LoadLargeTiffFromFile(string file) + /// A fully qualified path to a TIFF file. + /// When true, report the source + /// color depth from (as + /// does) instead of the decoded 32bpp value. The pixels are always decoded to + /// Rgba32 on this path regardless of the flag. + private void LoadLargeTiffFromFile(string file, bool preserveOriginalFormat) { Tiff.SetErrorHandler(new DisableErrorHandler()); @@ -3331,6 +3337,7 @@ private void LoadLargeTiffFromFile(string file) try { + // ReadTiffFrames also populates _framesOriginalBitsPerPixel (per-frame source depth). frames = ReadTiffFrames(tiff); } catch (DllNotFoundException e) @@ -3345,6 +3352,13 @@ private void LoadLargeTiffFromFile(string file) $"The TIFF file '{file}' was opened but contained no decodable image pages."); } + if (preserveOriginalFormat) + { + _originalBitsPerPixel = _framesOriginalBitsPerPixel != null && _framesOriginalBitsPerPixel.Count > 0 + ? _framesOriginalBitsPerPixel[0] + : null; + } + // Hold the decoded pages directly. Binary is deliberately NOT set: the // source file may be larger than a single byte[] can hold. The // _streamedFromTiff flag tells the Binary getter to re-encode the pages as