1 // Licensed to the .NET Foundation under one or more agreements.
2 // See the LICENSE file in the project root for more information.
3 //
4 // Authors:
5 // 	Jordi Mas i Hernàndez (jordi@ximian.com)
6 //	Sebastien Pouliot  <sebastien@ximian.com>
7 //
8 // (C) 2004 Ximian, Inc.  http://www.ximian.com
9 // Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System.Collections;
31 using System.Collections.Generic;
32 using System.Text.RegularExpressions;
33 using Xunit;
34 
35 namespace System.Drawing.Imaging.Tests
36 {
37     public class ImageCodecInfoTests
38     {
39         private const string GIF_CSID = "557cf402-1a04-11d3-9a73-0000f81ef32e";
40         private const string EMF_CSID = "557cf403-1a04-11d3-9a73-0000f81ef32e";
41         private const string BMP_DIB_RLE_CSID = "557cf400-1a04-11d3-9a73-0000f81ef32e";
42         private const string JPG_JPEG_JPE_JFIF_CSID = "557cf401-1a04-11d3-9a73-0000f81ef32e";
43         private const string PNG_CSID = "557cf406-1a04-11d3-9a73-0000f81ef32e";
44         private const string ICO_CSID = "557cf407-1a04-11d3-9a73-0000f81ef32e";
45         private const string WMF_CSID = "557cf404-1a04-11d3-9a73-0000f81ef32e";
46         private const string TIF_CSID = "557cf405-1a04-11d3-9a73-0000f81ef32e";
47 
48         private Hashtable decoders;
49         private Hashtable encoders;
50 
ImageCodecInfoTests()51         public ImageCodecInfoTests()
52         {
53             decoders = new Hashtable();
54             encoders = new Hashtable();
55 
56             foreach (ImageCodecInfo decoder in ImageCodecInfo.GetImageDecoders())
57                 decoders[decoder.Clsid] = decoder;
58 
59             foreach (ImageCodecInfo encoder in ImageCodecInfo.GetImageEncoders())
60                 encoders[encoder.Clsid] = encoder;
61         }
62 
GetEncoder(string clsid)63         private ImageCodecInfo GetEncoder(string clsid)
64         {
65             return (ImageCodecInfo)encoders[new Guid(clsid)];
66         }
67 
GetDecoder(string clsid)68         private ImageCodecInfo GetDecoder(string clsid)
69         {
70             return (ImageCodecInfo)decoders[new Guid(clsid)];
71         }
72 
CheckDecoderAndEncoder(string clsid, ImageFormat format, string CodecName, string DllName, string FilenameExtension, ImageCodecFlags Flags, string FormatDescription, string MimeType, int Version, int signatureLength, string mask, string pattern, string pattern2)73         private void CheckDecoderAndEncoder(string clsid, ImageFormat format, string CodecName, string DllName,
74             string FilenameExtension, ImageCodecFlags Flags, string FormatDescription,
75             string MimeType, int Version, int signatureLength, string mask, string pattern, string pattern2)
76         {
77             ImageCodecInfo encoder = GetEncoder(clsid);
78             ImageCodecInfo decoder = GetDecoder(clsid);
79 
80             if (encoder != null)
81             {
82                 CheckImageCodecInfo(format, CodecName, DllName, FilenameExtension, Flags, FormatDescription, MimeType, signatureLength, mask, pattern, pattern2, encoder);
83             }
84             if (decoder != null)
85             {
86                 CheckImageCodecInfo(format, CodecName, DllName, FilenameExtension, Flags, FormatDescription, MimeType, signatureLength, mask, pattern, pattern2, decoder);
87             }
88         }
89 
CheckImageCodecInfo(ImageFormat format, string CodecName, string DllName, string FilenameExtension, ImageCodecFlags Flags, string FormatDescription, string MimeType, int signatureLength, string mask, string pattern, string pattern2, ImageCodecInfo codecInfo)90         private void CheckImageCodecInfo(ImageFormat format, string CodecName, string DllName, string FilenameExtension, ImageCodecFlags Flags, string FormatDescription, string MimeType, int signatureLength, string mask, string pattern, string pattern2, ImageCodecInfo codecInfo)
91         {
92             Regex extRegex = new Regex(@"^(\*\.\w+(;(\*\.\w+))*;)?" +
93                 Regex.Escape(FilenameExtension) + @"(;\*\.\w+(;(\*\.\w+))*)?$",
94                 RegexOptions.IgnoreCase | RegexOptions.Singleline);
95 
96             Assert.Equal(format.Guid, codecInfo.FormatID);
97             Assert.Contains(CodecName, codecInfo.CodecName);
98             Assert.Equal(DllName, codecInfo.DllName);
99             Assert.True(extRegex.IsMatch(codecInfo.FilenameExtension));
100             Assert.Equal(Flags, codecInfo.Flags);
101             Assert.Contains(FormatDescription, codecInfo.FormatDescription);
102             Assert.Contains(MimeType, codecInfo.MimeType);
103             Assert.Equal(signatureLength, codecInfo.SignatureMasks.Length);
104 
105             for (int i = 0; i < signatureLength; i++)
106             {
107                 Assert.Equal(mask, BitConverter.ToString(codecInfo.SignatureMasks[i]));
108             }
109 
110             Assert.Equal(signatureLength, codecInfo.SignaturePatterns.Length);
111             Assert.Equal(pattern, BitConverter.ToString(codecInfo.SignaturePatterns[0]));
112             if (pattern2 != null)
113                 Assert.Equal(pattern2, BitConverter.ToString(codecInfo.SignaturePatterns[1]));
114         }
115 
116         public static IEnumerable<object[]> CodecInfoTestData
117         {
118             get
119             {
120                 yield return new object[] { WMF_CSID, ImageFormat.Wmf,
121                 "WMF", null, "*.WMF",
122                 ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
123                 "WMF", "image/x-wmf", 1, 1, "FF-FF-FF-FF", "D7-CD-C6-9A", null};
124 
125                 yield return new object[] { EMF_CSID, ImageFormat.Emf,
126                 "EMF", null, "*.EMF",
127                 ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
128                 "EMF", "image/x-emf", 1, 1, "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-FF-FF-FF-FF",
129                 "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-20-45-4D-46", null};
130 
131                 yield return new object[] { ICO_CSID, ImageFormat.Icon,
132                 "ICO", null, "*.ICO",
133                 ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
134                 "ICO", "image/x-icon", 1, 1, "FF-FF-FF-FF", "00-00-01-00", null};
135 
136                 yield return new object[] { TIF_CSID, ImageFormat.Tiff,
137                 "TIFF", null, "*.TIF;*.TIFF",
138                 ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
139                 "TIFF", "image/tiff", 1, 2, "FF-FF", "49-49", "4D-4D" };
140 
141                 yield return new object[] { PNG_CSID, ImageFormat.Png,
142                 "PNG", null, "*.PNG",
143                 ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
144                 "PNG", "image/png", 1, 1, "FF-FF-FF-FF-FF-FF-FF-FF", "89-50-4E-47-0D-0A-1A-0A", null };
145 
146                 yield return new object[] { JPG_JPEG_JPE_JFIF_CSID, ImageFormat.Jpeg,
147                 "JPEG", null, "*.JPG",
148                 ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
149                 "JPEG", "image/jpeg", 1, 1, "FF-FF", "FF-D8", null};
150 
151                 yield return new object[] { GIF_CSID, ImageFormat.Gif,
152                 "GIF", null, "*.GIF",
153                 ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
154                 "GIF", "image/gif", 1, 2, "FF-FF-FF-FF-FF-FF", "47-49-46-38-39-61", "47-49-46-38-37-61"};
155 
156                 yield return new object[] { BMP_DIB_RLE_CSID, ImageFormat.Bmp,
157                 "BMP", null, "*.BMP",
158                 ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
159                 "BMP", "image/bmp", 1, 1, "FF-FF", "42-4D", null };
160             }
161         }
162 
163         [ConditionalTheory(Helpers.GdiplusIsAvailable)]
164         [InlineData(GIF_CSID)]
165         [InlineData(EMF_CSID)]
166         [InlineData(BMP_DIB_RLE_CSID)]
167         [InlineData(JPG_JPEG_JPE_JFIF_CSID)]
168         [InlineData(PNG_CSID)]
169         [InlineData(ICO_CSID)]
170         [InlineData(WMF_CSID)]
171         [InlineData(TIF_CSID)]
GetDecoder_Success(string csid)172         public void GetDecoder_Success(string csid)
173         {
174             Assert.NotNull(GetDecoder(csid));
175         }
176 
177         [ConditionalTheory(Helpers.GdiplusIsAvailable)]
178         [InlineData(GIF_CSID)]
179         [InlineData(BMP_DIB_RLE_CSID)]
180         [InlineData(JPG_JPEG_JPE_JFIF_CSID)]
181         [InlineData(PNG_CSID)]
182         [InlineData(TIF_CSID)]
GetEncoder_Success(string csid)183         public void GetEncoder_Success(string csid)
184         {
185             Assert.NotNull(GetEncoder(csid));
186         }
187 
188         [ConditionalFact(Helpers.GdiplusIsAvailable)]
CountEncoders_ReturnsExcpected()189         public void CountEncoders_ReturnsExcpected()
190         {
191             Assert.Equal(5, encoders.Count);
192         }
193 
194         [ConditionalFact(Helpers.GdiplusIsAvailable)]
CountDecoders_ReturnsExcpected()195         public void CountDecoders_ReturnsExcpected()
196         {
197             Assert.Equal(8, decoders.Count);
198         }
199 
200         [ConditionalTheory(Helpers.GdiplusIsAvailable)]
201         [MemberData(nameof(CodecInfoTestData))]
CheckDecoderAndEncoder_ReturnsExpecetd(string clsid, ImageFormat format, string codecName, string dllName, string fileNameExtension, ImageCodecFlags flags, string formatDescription, string mimeType, int version, int signatureLength, string mask, string pattern, string pattern2)202         public void CheckDecoderAndEncoder_ReturnsExpecetd(string clsid, ImageFormat format, string codecName, string dllName,
203             string fileNameExtension, ImageCodecFlags flags, string formatDescription,
204             string mimeType, int version, int signatureLength, string mask, string pattern, string pattern2)
205         {
206             CheckDecoderAndEncoder(clsid, format, codecName, dllName, fileNameExtension, flags, formatDescription, mimeType, version, signatureLength, mask, pattern, pattern2);
207         }
208 
209         [ConditionalTheory(Helpers.GdiplusIsAvailable)]
210         [InlineData(WMF_CSID)]
211         [InlineData(EMF_CSID)]
212         [InlineData(ICO_CSID)]
GetEncoder_NoSuchEncoding_ReturnsNull(string clsid)213         public void GetEncoder_NoSuchEncoding_ReturnsNull(string clsid)
214         {
215             Assert.Null(GetEncoder(clsid));
216         }
217     }
218 }
219