Last active
December 15, 2015 12:09
-
-
Save jstedfast/5258318 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static ImageInfo ReadPng (string fileName) | |
{ | |
int w, h; | |
if (GetPngImageSize (fileName, out w, out h)) | |
return new ImageInfo { FileName = fileName, Width = w, Height = h }; | |
return new ImageInfo (); | |
} | |
public static ImageInfo ReadJpg (string fileName) | |
{ | |
int w, h; | |
if (GetJpgImageSize (fileName, out w, out h)) | |
return new ImageInfo { FileName = fileName, Width = w, Height = h }; | |
return new ImageInfo (); | |
} | |
public static ImageInfo Read (string fileName) | |
{ | |
ImageInfo info = ReadPng (fileName); | |
if (info.FileName == null) | |
info = ReadJpg (fileName); | |
return info; | |
} | |
static int ReadInt (BinaryReader reader) | |
{ | |
int result = 0; | |
result += (int)reader.ReadByte () << 24; | |
result += (int)reader.ReadByte () << 16; | |
result += (int)reader.ReadByte () << 8; | |
result += (int)reader.ReadByte (); | |
return result; | |
} | |
static bool GetPngImageSize (string fileName, out int width, out int height, bool tryReverting = true) | |
{ | |
// PNG file format specification can be found at: http://www.w3.org/TR/PNG | |
BinaryReader reader = null; | |
try { | |
reader = new BinaryReader (File.OpenRead (fileName)); | |
var pngHeader = reader.ReadBytes (8); | |
// Check for valid PNG header. | |
if (pngHeader[0] != 137 || | |
pngHeader[1] != 80 || pngHeader[2] != 78 || pngHeader [3] != 71 || | |
pngHeader [4] != 13 || pngHeader [5] != 10 || pngHeader [6] != 26 || pngHeader [7] != 10) | |
throw new IOException ("File has no valid PNG header."); | |
// First chunk is always the IHDR header chunk | |
reader.ReadBytes (4); // skip chunk size | |
var ihdrID = reader.ReadBytes (4); | |
if (ihdrID[0] == 73 && ihdrID[1] == 72 && ihdrID[2] == 68 && ihdrID[3] == 82) { | |
width = ReadInt (reader); | |
height = ReadInt (reader); | |
return true; | |
} | |
if (tryReverting) { | |
// Assumed to be an iOS app at this point, which means pngcrush may have made this file unreadable... | |
var pngcrush = AppleSdkSettings.DeveloperRoot.Combine ("Platforms", "iPhoneOS.platform", "Developer", "usr", "bin", "pngcrush"); | |
if (File.Exists (pngcrush)) { | |
var reverted = System.IO.Path.GetTempFileName (); | |
var args = new ProcessArgumentBuilder (); | |
args.Add ("-revert-iphone-optimizations"); | |
args.AddQuoted (fileName); | |
args.AddQuoted (reverted); | |
var output = new StringWriter (); | |
MonoDevelop.Core.Runtime.ProcessService.StartProcess (pngcrush, args.ToString (), "", output, output, null).WaitForExit (); | |
bool success = GetPngImageSize (reverted, out width, out height, false); | |
File.Delete (reverted); | |
return success; | |
} | |
} | |
throw new IOException ("IHDR missing or corrupt."); | |
} catch (Exception e) { | |
LoggingService.LogError ("Error while getting png image size of: " + fileName, e); | |
width = height = -1; | |
return false; | |
} finally { | |
if (reader != null) | |
reader.Close (); | |
} | |
} | |
static bool GetJpgImageSize (string filename, out int width, out int height) | |
{ | |
try { | |
var type = Pixbuf.GetFileInfo (filename, out width, out height); | |
return type != null && type.Name == "jpeg"; | |
} catch { | |
width = height = -1; | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment