/****************************** Module Header ******************************\ 
Module Name:    TiffImageConverter.cs 
Project:        CSTiffImageConverter
Copyright (c) Microsoft Corporation. 

The class defines the helper methods for converting TIFF from or to JPEG 
file(s)

This source is subject to the Microsoft Public License.
See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
All other rights reserved.

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
\***************************************************************************/

using System;
using System.IO;
using System.Linq;
using System.Drawing.Imaging;
using System.Drawing;
using System.Drawing.Drawing2D;


namespace CSTiffImageConverter
{
    public class TiffImageConverter
    { 
        /// <summary>
        /// Converts tiff imagae(s) to selected format image(s).
        /// </summary>
        /// <param name="fileName">Full name to tiff image.</param>
        /// <returns>String array having full name to selected format images.</returns>
        public static string[] ConvertFromTiff(string fileName, ImageFormat imageFormat)
        {
            using (Image imageFile = Image.FromFile(fileName))
            {
                FrameDimension frameDimensions = new FrameDimension(
                    imageFile.FrameDimensionsList[0]);

                // Gets the number of pages from the tiff image (if multipage)
                int frameNum = imageFile.GetFrameCount(frameDimensions);
                string[] imgPaths = new string[frameNum];

                for (int frame = 0; frame < frameNum; frame++)
                {
                    // Selects one frame at a time and save to the desired format.
                    imageFile.SelectActiveFrame(frameDimensions, frame);
                    using (Bitmap bmp = new Bitmap(imageFile))
                    {
                        imgPaths[frame] = String.Format("{0}\\{1}{2}." + imageFormat.ToString(),
                            Path.GetDirectoryName(fileName),
                            Path.GetFileNameWithoutExtension(fileName),
                            frame);
                        bmp.Save(imgPaths[frame], imageFormat);
                    }
                }

                return imgPaths;
            }
        }

        /// <summary>
        /// Converts selected format image(s) to tiff image(s).
        /// </summary>
        /// <param name="fileNames">
        /// String array having full name to selected format images.
        /// </param>
        /// <param name="isMultipage">
        /// true to create single multipage tiff file otherwise, false.
        /// </param>
        /// <returns>
        /// String array having full name to tiff images.
        /// </returns>
        public static string[] ConvertToTiff(string[] fileNames, bool isMultipage)
        {
            EncoderParameters encoderParams = new EncoderParameters(1);
            ImageCodecInfo tiffCodecInfo = ImageCodecInfo.GetImageEncoders()
                .First(ie => ie.MimeType == "image/tiff");

            string[] tiffPaths = null;
            if (isMultipage)
            {
                tiffPaths = new string[1];
                Image tiffImg = null;
                try
                {
                    for (int i = 0; i < fileNames.Length; i++)
                    {
                        if (i == 0)
                        {
                            tiffPaths[i] = String.Format("{0}\\{1}.tif",
                                Path.GetDirectoryName(fileNames[i]),
                                Path.GetFileNameWithoutExtension(fileNames[i]));

                            // Initialize the first frame of multipage tiff.
                            tiffImg = Image.FromFile(fileNames[i]);
                            encoderParams.Param[0] = new EncoderParameter(
                                Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
                            tiffImg.Save(tiffPaths[i], tiffCodecInfo, encoderParams);
                        }
                        else
                        {
                            // Add additional frames.
                            encoderParams.Param[0] = new EncoderParameter(
                                Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
                            using (Image frame = Image.FromFile(fileNames[i]))
                            {
                                tiffImg.SaveAdd(frame, encoderParams);
                            }
                        }

                        if (i == fileNames.Length - 1)
                        {
                            // When it is the last frame, flush the resources and closing.
                            encoderParams.Param[0] = new EncoderParameter(
                                Encoder.SaveFlag, (long)EncoderValue.Flush);
                            tiffImg.SaveAdd(encoderParams);
                        }
                    }
                }
                finally
                {
                    if (tiffImg != null)
                    {
                        tiffImg.Dispose();
                        tiffImg = null;
                    }
                }
            }
            else
            {
                tiffPaths = new string[fileNames.Length];

                for (int i = 0; i < fileNames.Length; i++)
                {
                    tiffPaths[i] = String.Format("{0}\\{1}.tif",
                        Path.GetDirectoryName(fileNames[i]),
                        Path.GetFileNameWithoutExtension(fileNames[i]));

                    // Save as individual tiff files.
                    using (Image tiffImg = Image.FromFile(fileNames[i]))
                    {
                        tiffImg.Save(tiffPaths[i], ImageFormat.Tiff);
                    }
                }
            }

            return tiffPaths;
        }

        /// <summary>
        /// Resize an image to 1024x768 px
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns>
        /// empty fileName : -1
        /// file does not exist : -2
        /// file already at the good size : 0
        /// resized ok : 1
        /// </returns>
        public static int ResizeImage(string fileName)
        {
            Size size = new Size(1024, 768);

            // Check if the fileName is empty
            if (fileName.Equals(""))
            {
                return -1;
            }

            // Check if the file exists
            if (!File.Exists(fileName))
            {
                return -2;
            }

            Image img = Image.FromFile(fileName);

            // Check if the file is already at the good size.
            if (img.Size == size)
            {
                return 0;
            }

            string resizedFileName;
            string format = Path.GetExtension(fileName);
            string directory = Path.GetDirectoryName(fileName);
            string name = Path.GetFileNameWithoutExtension(fileName);
            resizedFileName = String.Format("{0}\\{1}_resized{2}", directory, name, format);

            Bitmap resizedImg = new Bitmap(img, size);
            resizedImg.Save(resizedFileName);

            return 1;
        }
    }
}