/[Sims3RigEditor]/trunk/ViewDDS/DdsSquish.cs
ViewVC logotype

Contents of /trunk/ViewDDS/DdsSquish.cs

Parent Directory Parent Directory | Revision Log Revision Log


Revision 64 - (show annotations) (download)
Fri Aug 13 01:33:17 2010 UTC (9 years, 10 months ago) by william
File size: 10727 byte(s)
Add DXT2 & DXT4 support to DDS Plugin

1 //------------------------------------------------------------------------------
2 /*
3 @brief DDS File Type Plugin for Paint.NET
4
5 @note Copyright (c) 2007 Dean Ashton http://www.dmashton.co.uk
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **/
26 //------------------------------------------------------------------------------
27
28 using System;
29 using System.Collections.Generic;
30 using System.Text;
31 using System.Drawing;
32 using System.Runtime.InteropServices;
33 using PaintDotNet.SystemLayer;
34 //using PaintDotNet;
35 //using PaintDotNet.SystemLayer;
36
37 namespace DdsFileTypePlugin
38 {
39 internal sealed class DdsSquish
40 {
41 public enum SquishFlags
42 {
43 kDxt1 = (1 << 0), // Use DXT1 compression.
44 kDxt2 = (1 << 1), // Use DXT2 compression.
45 kDxt3 = (1 << 2), // Use DXT3 compression.
46 kDxt4 = (1 << 3), // Use DXT4 compression.
47 kDxt5 = (1 << 4), // Use DXT5 compression.
48
49 kColourClusterFit = (1 << 3), // Use a slow but high quality colour compressor (the default).
50 kColourRangeFit = (1 << 4), // Use a fast but low quality colour compressor.
51
52 kColourMetricPerceptual = (1 << 5), // Use a perceptual metric for colour error (the default).
53 kColourMetricUniform = (1 << 6), // Use a uniform metric for colour error.
54
55 kWeightColourByAlpha = (1 << 7), // Weight the colour by alpha during cluster fit (disabled by default).
56
57 kColourIterativeClusterFit = (1 << 8), // Use a very slow but very high quality colour compressor.
58 }
59
60 private static bool Is64Bit()
61 {
62 return (Marshal.SizeOf(IntPtr.Zero) == 8);
63 }
64
65 internal delegate void ProgressFn(int workDone, int workTotal);
66
67 private sealed class SquishInterface_32
68 {
69 [DllImport("squishinterface_Win32.dll")]
70 internal static extern unsafe void SquishCompressImage(byte* rgba, int width, int height, byte* blocks, int flags,
71 [MarshalAs(UnmanagedType.FunctionPtr)] ProgressFn progressFn);
72
73 [DllImport("squishinterface_Win32.dll")]
74 internal static extern unsafe void SquishDecompressImage(byte* rgba, int width, int height, byte* blocks, int flags,
75 [MarshalAs(UnmanagedType.FunctionPtr)] ProgressFn progressFn);
76
77 [DllImport("squishinterface_Win32.dll")]
78 internal static extern void SquishInitialize();
79 }
80
81 //private sealed class SquishInterface_32_SSE2
82 //{
83 // [DllImport("Squish_x86_SSE2.dll")]
84 // internal static extern unsafe void SquishCompressImage(byte* rgba, int width, int height, byte* blocks, int flags,
85 // [MarshalAs(UnmanagedType.FunctionPtr)] ProgressFn progressFn);
86
87 // [DllImport("Squish_x86_SSE2.dll")]
88 // internal static extern unsafe void SquishDecompressImage(byte* rgba, int width, int height, byte* blocks, int flags,
89 // [MarshalAs(UnmanagedType.FunctionPtr)] ProgressFn progressFn);
90
91 // [DllImport("Squish_x86_SSE2.dll")]
92 // internal static extern void SquishInitialize();
93 //}
94
95 private sealed class SquishInterface_64
96 {
97 [DllImport("squishinterface_x64.dll")]
98 internal static extern unsafe void SquishCompressImage(byte* rgba, int width, int height, byte* blocks, int flags,
99 [MarshalAs(UnmanagedType.FunctionPtr)] ProgressFn progressFn);
100
101 [DllImport("squishinterface_x64.dll")]
102 internal static extern unsafe void SquishDecompressImage(byte* rgba, int width, int height, byte* blocks, int flags,
103 [MarshalAs(UnmanagedType.FunctionPtr)] ProgressFn progressFn);
104
105 [DllImport("squishinterface_x64.dll")]
106 internal static extern void SquishInitialize();
107 }
108
109 private static unsafe void CallCompressImage(byte[] rgba, int width, int height, byte[] blocks, int flags, ProgressFn progressFn)
110 {
111 fixed (byte* pRGBA = rgba)
112 {
113 fixed (byte* pBlocks = blocks)
114 {
115 if (Processor.Architecture == ProcessorArchitecture.X64)
116 SquishInterface_64.SquishCompressImage(pRGBA, width, height, pBlocks, flags, progressFn);
117 //else if (Processor.IsFeaturePresent(ProcessorFeature.SSE2))
118 // SquishInterface_32_SSE2.SquishCompressImage(pRGBA, width, height, pBlocks, flags, progressFn);
119 else
120 SquishInterface_32.SquishCompressImage(pRGBA, width, height, pBlocks, flags, progressFn);
121 }
122 }
123
124 GC.KeepAlive(progressFn);
125 }
126
127 private static unsafe void CallDecompressImage(byte[] rgba, int width, int height, byte[] blocks, int flags, ProgressFn progressFn)
128 {
129 fixed (byte* pRGBA = rgba)
130 {
131 fixed (byte* pBlocks = blocks)
132 {
133 if (Processor.Architecture == ProcessorArchitecture.X64)
134 SquishInterface_64.SquishDecompressImage(pRGBA, width, height, pBlocks, flags, progressFn);
135 //else if (Processor.IsFeaturePresent(ProcessorFeature.SSE2))
136 // SquishInterface_32_SSE2.SquishDecompressImage(pRGBA, width, height, pBlocks, flags, progressFn);
137 else
138 SquishInterface_32.SquishDecompressImage(pRGBA, width, height, pBlocks, flags, progressFn);
139 }
140 }
141
142 GC.KeepAlive(progressFn);
143 }
144
145 public static void Initialize()
146 {
147 if (Processor.Architecture == ProcessorArchitecture.X64)
148 {
149 SquishInterface_64.SquishInitialize();
150 }
151 //else if (Processor.IsFeaturePresent(ProcessorFeature.SSE2))
152 //{
153 // SquishInterface_32_SSE2.SquishInitialize();
154 //}
155 else
156 {
157 SquishInterface_32.SquishInitialize();
158 }
159 }
160
161 // ---------------------------------------------------------------------------------------
162 // CompressImage
163 // ---------------------------------------------------------------------------------------
164 //
165 // Params
166 // inputSurface : Source byte array containing RGBA pixel data
167 // flags : Flags for squish compression control
168 //
169 // Return
170 // blockData : Array of bytes containing compressed blocks
171 //
172 // ---------------------------------------------------------------------------------------
173
174 //internal static byte[] CompressImage(Surface inputSurface, int squishFlags, ProgressFn progressFn)
175 //{
176 // // We need the input to be in a byte array for squish.. so create one.
177 // byte[] pixelData = new byte[inputSurface.Width * inputSurface.Height * 4];
178
179 // for (int y = 0; y < inputSurface.Height; y++)
180 // {
181 // for (int x = 0; x < inputSurface.Width; x++)
182 // {
183 // ColorBgra pixelColour = inputSurface.GetPoint(x, y);
184 // int pixelOffset = (y * inputSurface.Width * 4) + (x * 4);
185
186 // pixelData[pixelOffset + 0] = pixelColour.R;
187 // pixelData[pixelOffset + 1] = pixelColour.G;
188 // pixelData[pixelOffset + 2] = pixelColour.B;
189 // pixelData[pixelOffset + 3] = pixelColour.A;
190 // }
191 // }
192
193 // // Compute size of compressed block area, and allocate
194 // int blockCount = ((inputSurface.Width + 3) / 4) * ((inputSurface.Height + 3) / 4);
195 // int blockSize = ((squishFlags & (int)DdsSquish.SquishFlags.kDxt1) != 0) ? 8 : 16;
196
197 // // Allocate room for compressed blocks
198 // byte[] blockData = new byte[blockCount * blockSize];
199
200 // // Invoke squish::CompressImage() with the required parameters
201 // CallCompressImage(pixelData, inputSurface.Width, inputSurface.Height, blockData, squishFlags, progressFn);
202
203 // // Return our block data to caller..
204 // return blockData;
205 //}
206
207 // ---------------------------------------------------------------------------------------
208 // DecompressImage
209 // ---------------------------------------------------------------------------------------
210 //
211 // Params
212 // inputSurface : Source byte array containing DXT block data
213 // width : Width of image in pixels
214 // height : Height of image in pixels
215 // flags : Flags for squish decompression control
216 //
217 // Return
218 // byte[] : Array of bytes containing decompressed blocks
219 //
220 // ---------------------------------------------------------------------------------------
221
222 internal static byte[] DecompressImage(byte[] blocks, int width, int height, int flags)
223 {
224 // Allocate room for decompressed output
225 byte[] pixelOutput = new byte[width * height * 4];
226
227 // Invoke squish::DecompressImage() with the required parameters
228 CallDecompressImage(pixelOutput, width, height, blocks, flags, null);
229
230 // Return our pixel data to caller..
231 return pixelOutput;
232 }
233 }
234 }

  ViewVC Help
Powered by ViewVC 1.1.22