Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Module: TIFFTAGS.cs - Developed By: Arvo Bowen III - Version: 2012.02.25
- // References: BitMiracle.LibTiff.NET (BitMiracle.LibTiff.NET.dll)
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using BitMiracle.LibTiff.Classic;
- using System.Diagnostics;
- using System.IO;
- namespace LibNetDotNetSupport
- {
- #region TIFFTAGS_TAG Class
- public enum TIFFTAGS_TAG_DATATYPE { UNKNOWN = 0, ASCII = 2, SHORT = 3, LONG = 4, RATIONAL = 5 };
- public class TIFFTAGS_TAG
- {
- private TIFFTAGS_TAG_DATATYPE m_dtTagType;
- private Object m_oValue = null;
- private int m_iTagNumber = -1;
- private string m_sFileName = null;
- private int m_iPageNumber = -1;
- private string m_sTagName = null;
- //Constructor
- public TIFFTAGS_TAG()
- {
- TIFFTAGS_TAG_CONSTRUCTOR(null, -1, null);
- }
- public TIFFTAGS_TAG(string sFileName, int iTagNumber, Object oValue)
- {
- TIFFTAGS_TAG_CONSTRUCTOR(sFileName, iTagNumber, oValue);
- }
- private void TIFFTAGS_TAG_CONSTRUCTOR(string sFileName, int iTagNumber, Object oValue)
- {
- m_sFileName = sFileName;
- m_iTagNumber = iTagNumber;
- m_oValue = oValue;
- }
- //TagType
- public TIFFTAGS_TAG_DATATYPE TagType
- {
- get
- {
- //Determine the data type
- string sDataType = "";
- if (m_oValue.GetType().ToString() == "BitMiracle.LibTiff.Classic.FieldValue[]")
- {
- //Data type is a field value
- FieldValue[] fvValue = (FieldValue[])m_oValue;
- sDataType = fvValue[0].Value.GetType().ToString();
- }
- else
- {
- //Try to check a normal system data type because this one is not a field value
- sDataType = m_oValue.GetType().ToString();
- }
- switch (sDataType)
- {
- case "System.Int32":
- case "System.UInt32[]":
- case "BitMiracle.LibTiff.Classic.FileType":
- m_dtTagType = TIFFTAGS_TAG_DATATYPE.LONG;
- break;
- case "System.Int16":
- case "BitMiracle.LibTiff.Classic.Compression":
- case "BitMiracle.LibTiff.Classic.Photometric":
- case "BitMiracle.LibTiff.Classic.Threshold":
- case "BitMiracle.LibTiff.Classic.FillOrder":
- case "BitMiracle.LibTiff.Classic.Orientation":
- case "BitMiracle.LibTiff.Classic.PlanarConfig":
- case "BitMiracle.LibTiff.Classic.ResUnit":
- m_dtTagType = TIFFTAGS_TAG_DATATYPE.SHORT;
- break;
- case "System.String":
- case "System.Byte[]":
- m_dtTagType = TIFFTAGS_TAG_DATATYPE.ASCII;
- break;
- case "System.Single":
- m_dtTagType = TIFFTAGS_TAG_DATATYPE.RATIONAL;
- break;
- default:
- m_dtTagType = TIFFTAGS_TAG_DATATYPE.UNKNOWN;
- //Debug.WriteLine("Unknown TAG data type:" + fvValue[0].Value.GetType().ToString());
- break;
- }
- return m_dtTagType;
- }
- }
- //Value
- public Object Value
- {
- get
- {
- return m_oValue;
- }
- set
- {
- m_oValue = value;
- }
- }
- //TagNumber
- public int TagNumber
- {
- get
- {
- return m_iTagNumber;
- }
- set
- {
- m_iTagNumber = value;
- }
- }
- //FileName
- public string FileName
- {
- get
- {
- return m_sFileName;
- }
- set
- {
- m_sFileName = value;
- }
- }
- //PageNumber
- public int PageNumber
- {
- get
- {
- return m_iPageNumber;
- }
- set
- {
- m_iPageNumber = value;
- }
- }
- //TagName
- public string TagName
- {
- get
- {
- if (m_iTagNumber >= 0)
- {
- switch (m_iTagNumber)
- {
- case 37572:
- //GSCCCA Previous Page Tag
- m_sTagName = "GSCCCA_PREVIOUS_PAGE";
- break;
- case 37574:
- //GSCCCA Next Page Tag
- m_sTagName = "GSCCCA_NEXT_PAGE";
- break;
- default:
- //Convert the tag number to a tag name
- TiffTag tTag = (TiffTag)m_iTagNumber;
- m_sTagName = Enum.GetName(typeof(TiffTag), tTag);
- if (m_sTagName == null) m_sTagName = "UNKNOWN_TAG_NAME";
- break;
- }
- }
- else
- {
- //No tag number has been set
- m_sTagName = "NO_TAG_NUMBER_SET";
- }
- //Check if a tag name was not found
- if (m_sTagName == "") m_sTagName = "UNKNOWN_TAG_NAME";
- return m_sTagName;
- }
- }
- public string ValueToFlatString()
- {
- string sValue = "";
- if (m_oValue != null)
- {
- FieldValue[] fvValue = (FieldValue[])m_oValue;
- //Determine what type of value is being unpacked
- string sValueType = "";
- switch (fvValue[0].Value.GetType().ToString())
- {
- case "System.Byte[]":
- sValueType = "ascii";
- break;
- case "BitMiracle.LibTiff.Classic.FileType":
- case "System.Int32":
- if (fvValue.Count() == 2)
- {
- if (fvValue[1].Value.GetType().ToString() == "System.Byte[]") sValueType = "ascii";
- }
- else sValueType = "long";
- break;
- case "System.Int16":
- case "BitMiracle.LibTiff.Classic.Photometric":
- case "BitMiracle.LibTiff.Classic.Threshold":
- case "BitMiracle.LibTiff.Classic.FillOrder":
- case "BitMiracle.LibTiff.Classic.Orientation":
- case "BitMiracle.LibTiff.Classic.PlanarConfig":
- case "BitMiracle.LibTiff.Classic.ResUnit":
- sValueType = "short";
- break;
- case "BitMiracle.LibTiff.Classic.Compression":
- sValueType = "compression";
- break;
- case "System.UInt32[]":
- sValueType = "to_long";
- break;
- case "System.Single":
- sValueType = "rational";
- break;
- default:
- sValueType = fvValue[0].Value.GetType().ToString();
- break;
- }
- if (fvValue[0].Value != null)
- {
- switch (sValueType)
- {
- case "short":
- sValue = fvValue[0].ToShort().ToString();
- if (fvValue[0].ToShort().ToString() != fvValue[0].Value.ToString())
- {
- sValue += " [" + fvValue[0].Value.ToString() + "]";
- }
- break;
- case "long":
- sValue = fvValue[0].ToUInt().ToString();
- if (fvValue[0].ToUInt().ToString() != fvValue[0].Value.ToString())
- {
- sValue += " [" + fvValue[0].Value.ToString() + "]";
- }
- break;
- case "compression":
- //Known short value
- switch (fvValue[0].Value.ToString())
- {
- case "CCITT_T4":
- //Tiff G3 custom string
- sValue = "Group 3 Fax (CCITT T.4) [" + fvValue[0].ToShort() + "]";
- break;
- case "CCITT_T6":
- //Tiff G4 custom string
- sValue = "Group 4 Fax (CCITT T.6) [" + fvValue[0].ToShort() + "]";
- break;
- default:
- //All other values
- sValue = fvValue[0].ToShort().ToString();
- if (fvValue[0].ToShort().ToString() != fvValue[0].Value.ToString())
- {
- sValue += " [" + fvValue[0].Value.ToString() + "]";
- }
- break;
- }
- break;
- case "to_long":
- //This will be a long value when all parts of the array are combined
- foreach (UInt32 oValue in (UInt32[])fvValue[0].Value)
- {
- sValue += (oValue.ToString() != "" ? oValue.ToString() : "0");
- }
- break;
- case "ascii":
- //Byte array to be converted to a string (make sure to trim all the null characters off the end)
- sValue = System.Text.ASCIIEncoding.ASCII.GetString((Byte[])fvValue[(fvValue.Count() - 1)].Value).TrimEnd('\0');
- break;
- case "rational":
- sValue = ToFraction(Convert.ToDecimal(fvValue[0].Value.ToString()));
- break;
- default:
- //All other values are assumed to be available using the ToString() methods
- Debug.WriteLine(fvValue[0].Value.GetType().ToString());
- sValue = "TYPE NOT SUPPORTED" + fvValue[0].Value.ToString();
- break;
- }
- }
- }
- return sValue;
- }
- private static string ToFraction(decimal value)
- {
- // get the whole value of the fraction
- decimal mWhole = Math.Truncate(value);
- // get the fractional value
- decimal mFraction = value - mWhole;
- // initialize a numerator and denomintar
- uint mNumerator = 0;
- uint mDenomenator = 1;
- // ensure that there is actual a fraction
- if (mFraction > 0m)
- {
- // convert the value to a string so that you can count the number of decimal places there are
- string strFraction = mFraction.ToString().Remove(0, 2);
- // store teh number of decimal places
- uint intFractLength = (uint)strFraction.Length;
- // set the numerator to have the proper amount of zeros
- mNumerator = (uint)Math.Pow(10, intFractLength);
- // parse the fraction value to an integer that equals [fraction value] * 10^[number of decimal places]
- uint.TryParse(strFraction, out mDenomenator);
- // get the greatest common divisor for both numbers
- uint gcd = GreatestCommonDivisor(mDenomenator, mNumerator);
- // divide the numerator and the denominator by the gratest common divisor
- mNumerator = mNumerator / gcd;
- mDenomenator = mDenomenator / gcd;
- }
- // create a string builder
- StringBuilder mBuilder = new StringBuilder();
- // add the whole number if it's greater than 0
- if (mWhole > 0m)
- {
- mBuilder.Append(mWhole);
- }
- // add the fraction if it's greater than 0m
- if (mFraction > 0m)
- {
- if (mBuilder.Length > 0)
- {
- mBuilder.Append(" ");
- }
- mBuilder.Append(mDenomenator);
- mBuilder.Append("/");
- mBuilder.Append(mNumerator);
- }
- // add the whole number over 1 if the number is not a decimal
- if (!mBuilder.ToString().Contains('/')) mBuilder.Append("/1");
- return mBuilder.ToString();
- }
- private static decimal ToDecimal(string value)
- {
- String[] sSplit = value.Split('/');
- if (sSplit.Length != 2) return -1;
- try
- {
- decimal dNumerator = System.Convert.ToInt32(sSplit[0]);
- decimal dDenominator = System.Convert.ToInt32(sSplit[1]);
- return (dNumerator / dDenominator);
- }
- catch
- {
- //Error
- return -1;
- }
- }
- private static uint GreatestCommonDivisor(uint valA, uint valB)
- {
- // return 0 if both values are 0 (no GSD)
- if (valA == 0 &&
- valB == 0)
- {
- return 0;
- }
- // return value b if only a == 0
- else if (valA == 0 &&
- valB != 0)
- {
- return valB;
- }
- // return value a if only b == 0
- else if (valA != 0 && valB == 0)
- {
- return valA;
- }
- // actually find the GSD
- else
- {
- uint first = valA;
- uint second = valB;
- while (first != second)
- {
- if (first > second)
- {
- first = first - second;
- }
- else
- {
- second = second - first;
- }
- }
- return first;
- }
- }
- }
- #endregion
- public static class TIFFTAGS
- {
- #region TIFFTAGS_PAGE Class
- private class TIFFTAGS_PAGE
- {
- private int m_iHeight;
- private Dictionary<ushort, FieldValue[]> m_dTags;
- private byte[] m_bytePageData;
- private bool m_bEncoded;
- private int m_iStripSize;
- private int m_iStripOffset;
- //Constructor
- public TIFFTAGS_PAGE()
- {
- m_iHeight = 0;
- m_dTags = new Dictionary<ushort, FieldValue[]>();
- m_bytePageData = null;
- m_bEncoded = false;
- m_iStripSize = 0;
- }
- //Height
- public int Height
- {
- get
- {
- return m_iHeight;
- }
- set
- {
- m_iHeight = value;
- }
- }
- //Tags
- public Dictionary<ushort, FieldValue[]> Tags
- {
- get
- {
- return m_dTags;
- }
- set
- {
- m_dTags = value;
- }
- }
- //PageData
- public byte[] PageData
- {
- get
- {
- return m_bytePageData;
- }
- set
- {
- m_bytePageData = value;
- }
- }
- //Encoded
- public bool Encoded
- {
- get
- {
- return m_bEncoded;
- }
- set
- {
- m_bEncoded = value;
- }
- }
- //StripSize
- public int StripSize
- {
- get
- {
- return m_iStripSize;
- }
- set
- {
- m_iStripSize = value;
- }
- }
- //StripOffset
- public int StripOffset
- {
- get
- {
- return m_iStripOffset;
- }
- set
- {
- m_iStripOffset = value;
- }
- }
- }
- #endregion
- private static Tiff.TiffExtendProc m_parentExtender;
- private static List<TIFFTAGS_TAG> m_lTagsToWrite;
- private static void TagExtender(Tiff tif)
- {
- List<TiffFieldInfo> tfInfo = new List<TiffFieldInfo>();
- Int16 readCount = 0;
- Int16 writeCount = 0;
- bool okToChange = false;
- bool passCount = false;
- //Make sure to create a new tiff field info for all the tags to be written
- foreach (TIFFTAGS_TAG ttTag in m_lTagsToWrite)
- {
- switch (ttTag.TagType)
- {
- case TIFFTAGS_TAG_DATATYPE.ASCII:
- readCount = -1;
- writeCount = -1;
- okToChange = true;
- passCount = false;
- break;
- case TIFFTAGS_TAG_DATATYPE.LONG:
- case TIFFTAGS_TAG_DATATYPE.RATIONAL:
- case TIFFTAGS_TAG_DATATYPE.SHORT:
- readCount = 2;
- writeCount = 2;
- okToChange = false;
- passCount = true;
- break;
- }
- if (ttTag.TagType != TIFFTAGS_TAG_DATATYPE.UNKNOWN)
- {
- //Add the new item to the list
- tfInfo.Add(new TiffFieldInfo((TiffTag)ttTag.TagNumber, readCount, writeCount, (TiffType)ttTag.TagType, FieldBit.Custom, okToChange, passCount, ttTag.TagName));
- }
- }
- //Turn the list into an array again
- TiffFieldInfo[] tfInfoArray = tfInfo.ToArray();
- //Add the fields to the main field info area
- tif.MergeFieldInfo(tfInfoArray, tfInfoArray.Length);
- //Propergate the chain if needed
- if (m_parentExtender != null)
- m_parentExtender(tif);
- }
- public static bool DeleteTiffTag(string sFileName, ushort ushortTagNumber)
- {
- //Deletes a tiff tag from the given image
- //Returns true if successful or false if error occured
- try
- {
- //Reuse the main DeleteTiffTags function
- return DeleteTiffTags(sFileName, new List<ushort>(new ushort[] { ushortTagNumber }));
- }
- catch { return false; }
- }
- public static bool DeleteTiffTags(string sFileName, List<ushort> ushortTagNumbers)
- {
- //Deletes a list of tiff tag from the given image
- //Returns true if successful or false if error occured
- //Define variables
- List<TIFFTAGS_PAGE> ttPage = new List<TIFFTAGS_PAGE>();
- //Check for empty list
- if (ushortTagNumbers.Count == 0) return false;
- try
- {
- //ADDED
- m_lTagsToWrite = new List<TIFFTAGS_TAG>();
- m_lTagsToWrite.Add(new TIFFTAGS_TAG("", 38001, Convert.ToString("")));
- m_lTagsToWrite.Add(new TIFFTAGS_TAG("", 38002, Convert.ToString("")));
- m_parentExtender = Tiff.SetTagExtender(TagExtender);
- //Open the file for reading
- using (Tiff input = Tiff.Open(sFileName, "r"))
- {
- if (input == null) return false;
- //Get page count
- int numberOfDirectories = input.NumberOfDirectories();
- //Go through all the pages
- for (short i = 0; i < numberOfDirectories; ++i)
- {
- //Set the page
- input.SetDirectory(i);
- //Create a new tags dictionary to store all my tags
- Dictionary<ushort, FieldValue[]> dTags = new Dictionary<ushort, FieldValue[]>();
- //Get all the tags for the page
- for (ushort t = ushort.MinValue; t < ushort.MaxValue; ++t)
- {
- TiffTag tag = (TiffTag)t;
- FieldValue[] tagValue = input.GetField(tag);
- if (tagValue != null)
- {
- dTags.Add(t, tagValue);
- }
- }
- //Check if the page is encoded
- bool encoded = false;
- FieldValue[] compressionTagValue = input.GetField(TiffTag.COMPRESSION);
- if (compressionTagValue != null)
- encoded = (compressionTagValue[0].ToInt() != (int)Compression.NONE);
- //Create a new byte array to store all my image data
- int numberOfStrips = input.NumberOfStrips();
- byte[] byteImageData = new byte[numberOfStrips * input.StripSize()];
- int offset = 0;
- //Get all the image data for the page
- for (int n = 0; n < numberOfStrips; ++n)
- {
- int bytesRead;
- if (encoded)
- bytesRead = input.ReadEncodedStrip(n, byteImageData, offset, byteImageData.Length - offset);
- else
- bytesRead = input.ReadRawStrip(n, byteImageData, offset, byteImageData.Length - offset);
- //Add to the offset keeping up with where we are
- offset += bytesRead;
- }
- //Save all the tags, image data, and height, etc for the page
- TIFFTAGS_PAGE tiffPage = new TIFFTAGS_PAGE();
- tiffPage.Height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
- tiffPage.Tags = dTags;
- tiffPage.PageData = byteImageData;
- tiffPage.Encoded = encoded;
- tiffPage.StripSize = input.StripSize();
- tiffPage.StripOffset = input.GetField(TiffTag.STRIPOFFSETS)[0].ToIntArray()[0];
- ttPage.Add(tiffPage);
- }
- }
- //Open the file for writing
- using (Tiff output = Tiff.Open(sFileName + "-new.tif", "w"))
- {
- if (output == null) return false;
- //Go through all the pages
- for (short i = 0; i < ttPage.Count(); ++i)
- {
- //Write all the tags for the page
- foreach (KeyValuePair<ushort, FieldValue[]> tagValue in ttPage[i].Tags)
- {
- //Write all the tags except the one's needing to be deleted
- if (!ushortTagNumbers.Contains(tagValue.Key))
- {
- TiffTag tag = (TiffTag)tagValue.Key;
- output.GetTagMethods().SetField(output, tag, tagValue.Value);
- }
- }
- //Set the height for the page
- output.SetField(TiffTag.ROWSPERSTRIP, ttPage[i].Height);
- //Set the offset for the page
- output.SetField(TiffTag.STRIPOFFSETS, ttPage[i].StripOffset);
- //Save page data along with tags
- output.CheckpointDirectory();
- //Write each strip one at a time using the same orginal strip size
- int numberOfStrips = ttPage[i].PageData.Length / ttPage[i].StripSize;
- int offset = 0;
- for (int n = 0; n < numberOfStrips; ++n)
- {
- //Write all the image data (strips) for the page
- if (ttPage[i].Encoded)
- //output.WriteEncodedStrip(n, byteStrip, offset, byteStrip.Length - offset);
- output.WriteEncodedStrip(0, ttPage[i].PageData, offset, ttPage[i].StripSize - offset);
- else
- output.WriteRawStrip(n, ttPage[i].PageData, offset, ttPage[i].StripSize - offset);
- //Add to the offset keeping up with where we are
- offset += ttPage[i].StripOffset;
- }
- //Save the image page
- output.WriteDirectory();
- }
- }
- //ADDED
- Tiff.SetTagExtender(m_parentExtender);
- }
- catch
- {
- //ADDED
- Tiff.SetTagExtender(m_parentExtender);
- //Error occured
- return false;
- }
- //Return success
- return true;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement