From bb0a9fea2f85716efe3bc25ed34877b45cb8e3e8 Mon Sep 17 00:00:00 2001
From: Dzenan Zukic <dzenanz@gmail.com>
Date: Wed, 12 Dec 2012 09:39:31 +0100
Subject: [PATCH] BUG: PNGImageIO no longer uses invalid units in sCAL chunk

Change-Id: Iae27ef5f95c669a5a438313a15b0af7ad3514996
---

diff --git a/Modules/IO/PNG/src/itkPNGImageIO.cxx b/Modules/IO/PNG/src/itkPNGImageIO.cxx
index 93a83c1..f7864ba 100644
--- a/Modules/IO/PNG/src/itkPNGImageIO.cxx
+++ b/Modules/IO/PNG/src/itkPNGImageIO.cxx
@@ -413,12 +413,23 @@
 
   // see if the PNG file stored spacing information,
   // ignore the units (for now).
-  double px_width = 1.0, px_height = 1.0; // use default values if not in file
-  int    units = PNG_SCALE_UNKNOWN;
-  png_get_sCAL(png_ptr, info_ptr, &units, &px_width, &px_height);
-
-  m_Spacing[0] = px_width;
-  m_Spacing[1] = px_height;
+  int units = PNG_RESOLUTION_UNKNOWN;
+  png_uint_32 xres;
+  png_uint_32 yres;
+  if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &units)) //pHYs chunk is present
+    {
+    m_Spacing[0] = 2835.0 / xres;
+    m_Spacing[1] = 2835.0 / yres;
+    }
+  else //use sCAL chunk with fallback to default 1x1
+    {
+    units = PNG_SCALE_UNKNOWN;
+    double px_width = 1.0;
+    double px_height = 1.0; // use default values if not in file
+    png_get_sCAL(png_ptr, info_ptr, &units, &px_width, &px_height);
+    m_Spacing[0] = px_width;
+    m_Spacing[1] = px_height;
+    }
 
   // clean up
   png_destroy_read_struct(&png_ptr, &info_ptr,
@@ -589,9 +600,10 @@
   //      set the unit_type to unknown.  if we add units to ITK, we should
   //          convert pixel size to meters and store units as meters (png
   //          has three set of units: meters, radians, and unknown).
+  //          PNG_RESOLUTION_METER should go with Math::Round(1.0/colSpacing)
 #if (PNG_LIBPNG_VER_MAJOR < 2 && PNG_LIBPNG_VER_MINOR < 4)
-  png_set_sCAL(png_ptr, info_ptr, PNG_SCALE_UNKNOWN, colSpacing,
-               rowSpacing);
+  png_set_pHYs(png_ptr, info_ptr, Math::Round<png_uint_32>(2835.0/colSpacing),
+               Math::Round<png_uint_32>(2835.0/rowSpacing), PNG_RESOLUTION_UNKNOWN);
 #endif
 
   //std::cout << "PNG_INFO_sBIT: " << PNG_INFO_sBIT << std::endl;
