Skip to content
Open
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions src/Tesseract/Interop/LeptonicaApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ public interface ILeptonicaApiSignatures
[RuntimeDllImport(Constants.LeptonicaDllName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "pixReadMemTiff")]
unsafe IntPtr pixReadMemTiff(byte* data, int length, int page);

[RuntimeDllImport(Constants.LeptonicaDllName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "pixReadFromMultipageTiff")]
IntPtr pixReadFromMultipageTiff(string filename, ref int offset);

[RuntimeDllImport(Constants.LeptonicaDllName, CallingConvention = CallingConvention.Cdecl, EntryPoint = "pixWrite")]
int pixWrite(string filename, HandleRef handle, ImageFormat format);

Expand Down
1 change: 1 addition & 0 deletions src/Tesseract/Tesseract.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
</Compile>
<Compile Include="TesseractException.cs" />
<Compile Include="TextLineOrder.cs" />
<Compile Include="TiffReader.cs" />
<Compile Include="WritingDirection.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
109 changes: 109 additions & 0 deletions src/Tesseract/TiffReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.IO;

namespace Tesseract
{
/// <summary>
/// Access TIFF images one at a time to limit memory utilization.
/// </summary>
public sealed class TiffReader
{
/// <summary>
/// The file being read.
/// </summary>
private string Filename { get; set; }

/// <summary>
/// IFD offset cache.
/// </summary>
private List<int> Offsets { get; set; } = new List<int>();

/// <summary>
/// When true EOF was encountered and there are no more IFDs.
/// </summary>
private bool reachedEndOfFile = false;

/// <summary>
/// Initialize an instance of TiffReader for the specified file.
/// </summary>
/// <param name="filename">The path to the TIFF file to read.</param>
public TiffReader(string filename)
{
if (filename == null || filename == string.Empty)
{
throw new ArgumentOutOfRangeException("filename");
}

Filename = filename;
Offsets.Add(0);
}

/// <summary>
/// Get an image corresponding to the TIFF's IFD number using the offset cache. If the offset has not
/// been previously visited then the request is rejected.
/// </summary>
/// <param name="i">The IFD number, origin zero.</param>
/// <returns>null if the IFD isn't present, or the image.</returns>
public Pix GetPix(int i)
{
int offset = 0;
if (i < Offsets.Count)
{
offset = Offsets[i];
}
else
{
throw new IOException("Invalid sequence.");
}

IntPtr handle = Interop.LeptonicaApi.Native.pixReadFromMultipageTiff(Filename, ref offset);

if (handle == IntPtr.Zero)
{
return null;
}

return Pix.Create(handle);
}

/// <summary>
/// Get the next IFD entry from this TIFF.
/// </summary>
/// <returns>null if there are no more images.</returns>
public Pix NextPix()
{
if (reachedEndOfFile)
{
return null;
}

IntPtr handle;
if (Offsets.Count > 0)
{
int offset = Offsets[Offsets.Count - 1];
handle = Interop.LeptonicaApi.Native.pixReadFromMultipageTiff(Filename, ref offset);

if (handle == IntPtr.Zero)
{
return null;
}

if (offset != 0)
{
Offsets.Add(offset);
}
else
{
reachedEndOfFile = true;
}
}
else
{
throw new IOException("Invalid state.");
}

return Pix.Create(handle);
}
}
}