Fixing Group 3 Fax Resolution in iTextSharp

A client was having problems with attachments that we were sending out from their system. They receive faxes from their customers with authorizations that they need to, in turn, send out to doctor’s offices to obtain information.

The original files are in tiff format and typically faxed to them. Faxes arrive in either CCITT Group 3 or Group 4 fax format. We convert these tiff files to pdf using iTextSharp prior to processing them via fax, print or email (sent as an attachment). The problem we had is that most of the time the authorizations were fine, but sometimes they appeared squashed. By squashed I mean that the width was fine but height seemed to be 50% of what it should be. This seemed to be a random issue and when viewing the original documents in Irfanview or Windows Viewer they looked fine.

Photoshop-Pixel aspect ratio correction is for preview only. Turn it off for maximum image quality.

When I attempted to open the original files in Photoshop I received the following message.

I had seen this message before when opening tiffs and thought perhaps Photoshop wasn’t the best way to view them because I didn’t understand what it was telling me. I finally looked at the image size and realized that the original tiff file resolution was 200dpi for the width and 100dpi for the height. This explained what I was seeing.

What You Don’t Know Can Hurt You

I’ve worked with tiff files for several years and never had this issue so I did some digging. I found in this Wikipedia post that the Group 3 fax resolutions are defined as follows:

  • Horizontal: 100 scan lines per inch
    • Vertical: 100 scan lines per inch (“Basic”)
  • Horizontal: 200 or 204 scan lines per inch
    • Vertical: 100 or 98 scan lines per inch (“Standard”)
    • Vertical: 200 or 196 scan lines per inch (“Fine”)
    • Vertical: 400 or 391 (note not 392) scan lines per inch (“Superfine”)
  • Horizontal: 300 scan lines per inch
    • Vertical: 300 scan lines per inch
  • Horizontal: 400 or 408 scan lines per inch
    • Vertical: 400 or 391 scan lines per inch (“Ultrafine”)

That’s right, the resolutions don’t match for Class 3 “Standard”. Some standard! This, in effect, generates a document that has rectangular pixels rather than square. At least I knew that this wasn’t an isolated incident any more and knew what needed to be addressed. But what to do?

The Problem Was Two-Fold

With iTextSharp we were using the following code to scale the image to size.

img.ScaleToFit(wd, ht);

Then adding the image to a cell as follows:

PdfPCell cell = new PdfPCell();

Knowing that I needed to modify the resolution of the height if it was a “Standard” Class 3 fax was one thing, but I couldn’t find what I needed in the iTextSharp documentation. Time for some trial and error.

I attempted to modify the height resolution by using the SetDpi function which did in fact change the resolution. I verified this by stepping through the code and ensuring the properties of the image were being changed. I coupled that with img.SacleAbsolute(wd, ht) and thought I was out of the woods. However, it still generated the disproportionate document!

After trying other things to no avail and searching on forums I finally hit on this post that mentioned that adding the cell to the table in the way that we were doing ignored image scaling. After making the suggested change it finally generated the document correctly.

The final issue to address was to ensure that it wouldn’t always use the ScaleAbsolute because that could be problematic and after all, our code had worked on most of the documents. Rather than take a chance of causing issues with the majority of documents while fixing the few, it made sense to only do things the new way under the specific conditions we found.

The simplest way to accomplish this was to check to see if the horizontal and vertical resolutions match or not. If they do I use img.SetDpi(wd,ht) to alter the resolution creating a “square pixel”. Then make the call to img.SetAbsolute. When the resolutions match as they do in most of the documents then I only need to use img.ScaletoFit as we were doing originally.

This is the final code and it works for any resolution combination.

if (img.DpiX > img.DpiY) {
img.SetDpi(img.DpiX, img.DpiX);
scaletofit = false;
} else if (img.DpiY > img.DpiX) {
img.SetDpi(img.DpiY, img.DpiY);
scaletofit = false;
if (scaletofit) {
img.ScaleToFit(wd, ht);
} else {
img.ScaleAbsolute(wd, ht);
img.SetAbsolutePosition(0, 0);
PdfPTable table = new PdfPTable(1);
table.AddCell(new PdfPCell(img));