Skip to content

AccessViolationException when applying adaptive histogram to large images #1429

Description

@nullpainter

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

When applying an adaptive histogram equalisation to a 21,969 x 9802px image, I receive the following:

Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at SixLabors.ImageSharp.Processing.Processors.Normalization.AdaptiveHistogramEqualizationProcessor`1.CdfTileData.RowIntervalOperation.Invoke(RowInterval& rows)
   at SixLabors.ImageSharp.Advanced.ParallelRowIterator.RowIntervalOperationWrapper`1.Invoke(Int32 i)
   at System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.<ForWorker>b__1()
   at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
   at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)
   at System.Threading.Tasks.Task.Execute()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
   at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

Steps to Reproduce

This can be easily replicated using the following code, which fails fast:

using var image = new Image<Rgba32>(20000, 10000);
image.Mutate(c => c.HistogramEqualization(new HistogramEqualizationOptions
{
    Method = HistogramEqualizationMethod.AdaptiveTileInterpolation, 
    ClipHistogram = true
}));

I haven't looked at the code at all, but given the speed at which this fails compared with the length of time it takes to equalise a 10,000px square image, I am assuming this crash happens early in the process during memory allocation.

(Apologies for attempting to process gigantic images)

System Configuration

  • ImageSharp version: 1.0.2
  • Other ImageSharp packages and versions:
  • Environment (Operating system, version and so on): Windows 10
  • .NET Framework version: .NET Core 5.0

Activity

  1. JimBobSquarePants commented on Nov 16, 2020

    @JimBobSquarePants
    Member

    Can you supply the image?

  2. antonfirsov commented on Nov 16, 2020

    @antonfirsov
    Member

    Can you supply the image?

    According to the OP I think this is it:

    using var image = new Image<Rgba32>(20000, 10000);

    I suppose there is an index overflow here:

    Unsafe.Add(ref cdfMinBase, cdfX) = this.processor.CalculateCdf(ref cdfBase, ref histogramBase, histogram.Length - 1);

    I think we should limit usages of Unsafe.* to the essentially critical (and well covered) LoadResizeSave stuff (JPEG, Resize, maybe PNG), and remove it from all other processors. Span indexer is fast.

  3. self-assigned this
    on Nov 16, 2020
  4. brianpopow commented on Nov 16, 2020

    @brianpopow
    Collaborator

    I can reproduce the issue. I will change the pixel access to use GetPixelRowSpan there.

  5. modified the milestones: Future, on Nov 16, 2020
  6. added a commit that references this issue on Nov 16, 2020
    7040ca7
  7. added a commit that references this issue on Mar 13, 2021
    440d8cf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions