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

Update UnpackComponents() to account for 1bpc + DeviceGray (hack for Jbig2) #978

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions src/UglyToad.PdfPig/Images/ColorSpaceDetailsByteConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static ReadOnlySpan<byte> Convert(ColorSpaceDetails details, ReadOnlySpan
if (bitsPerComponent != 8)
{
// Unpack components such that they occupy one byte each
data = UnpackComponents(data, bitsPerComponent);
data = UnpackComponents(data, bitsPerComponent, details.Type);
}

// Remove padding bytes when the stride width differs from the image width
Expand All @@ -48,7 +48,7 @@ public static ReadOnlySpan<byte> Convert(ColorSpaceDetails details, ReadOnlySpan
return details.Transform(data);
}

private static Span<byte> UnpackComponents(Span<byte> input, int bitsPerComponent)
private static Span<byte> UnpackComponents(Span<byte> input, int bitsPerComponent, ColorSpace colorSpace)
{
if (bitsPerComponent == 16) // Example with MOZILLA-3136-0.pdf (page 3)
{
Expand All @@ -72,6 +72,24 @@ private static Span<byte> UnpackComponents(Span<byte> input, int bitsPerComponen
int right = (int)Math.Pow(2, bitsPerComponent) - 1;

int u = 0;

// TODO - 1bpc + DeviceGray is required for JBIG2 but needs to be investigated
// Why is this required? This does not belong here imo
if (bitsPerComponent == 1 && colorSpace != ColorSpace.Indexed)
{
foreach (byte b in input)
{
// Enumerate bits in bitsPerComponent-sized chunks from MSB to LSB, masking on the appropriate bits
for (int i = end; i >= 0; --i)
{
unpacked[u++] = (byte)((b >> i) & right) == 1 ? byte.MinValue : byte.MaxValue;
}
}

return unpacked;
}

// Default method
foreach (byte b in input)
{
// Enumerate bits in bitsPerComponent-sized chunks from MSB to LSB, masking on the appropriate bits
Expand Down
Loading