4 using System.Collections.Generic;
6 using System.Threading.Tasks;
8 using SiliconStudio.Paradox.Games;
9 using SiliconStudio.Paradox.Graphics;
10 using SiliconStudio.Core;
11 using SiliconStudio.Core.Diagnostics;
12 using SiliconStudio.TextureConverter.Requests;
15 namespace SiliconStudio.TextureConverter.TexLibraries
21 internal class ParadoxTextureLibraryData : ITextureLibraryData
26 public Image PdxImage;
33 internal class ParadoxTexLibrary : ITexLibrary
35 private static Logger Log = GlobalLogger.GetLogger(
"ParadoxTexLibrary");
36 public static readonly
string Extension =
".pdx";
41 public ParadoxTexLibrary(){}
46 public void Dispose(){}
49 public void Dispose(TexImage image)
51 ParadoxTextureLibraryData libraryData = (ParadoxTextureLibraryData)image.LibraryData[
this];
52 if (libraryData.PdxImage != null) libraryData.PdxImage.Dispose();
55 public bool SupportBGRAOrder()
60 public void StartLibrary(TexImage image)
62 ParadoxTextureLibraryData libraryData =
new ParadoxTextureLibraryData();
63 image.LibraryData[
this] = libraryData;
66 public void EndLibrary(TexImage image)
71 public bool CanHandleRequest(TexImage image, IRequest request)
75 case RequestType.Export:
77 string extension = Path.GetExtension(((ExportRequest)request).FilePath);
78 return extension.Equals(
".dds") || extension.Equals(Extension);
81 case RequestType.ExportToParadox:
84 case RequestType.Loading:
85 LoadingRequest load = (LoadingRequest)request;
86 if(load.Mode == LoadingRequest.LoadingMode.PdxImage)
return true;
87 else if(load.Mode == LoadingRequest.LoadingMode.FilePath)
89 string extension = Path.GetExtension(load.FilePath);
90 return extension.Equals(
".dds") || extension.Equals(Extension);
97 public void Execute(TexImage image, IRequest request)
99 ParadoxTextureLibraryData libraryData = image.LibraryData.ContainsKey(
this) ? (ParadoxTextureLibraryData)image.LibraryData[this] : null;
103 case RequestType.Export:
104 Export(image, libraryData, (ExportRequest)request);
107 case RequestType.ExportToParadox:
111 case RequestType.Loading:
112 Load(image, (LoadingRequest)request);
131 private void Export(TexImage image, ParadoxTextureLibraryData libraryDataf, ExportRequest request)
133 Log.Info(
"Exporting to " + request.FilePath +
" ...");
135 Image pdxImage = null;
137 if (request.MinimumMipMapSize > 1)
139 if (image.Dimension == TexImage.TextureDimension.Texture3D)
142 int newMipMapCount = 0;
144 int curDepth = image.Depth << 1;
145 for (
int i = 0; i < image.MipmapCount; ++i)
147 curDepth = curDepth > 1 ? curDepth >>= 1 : curDepth;
149 if (image.SubImageArray[ct].Width <= request.MinimumMipMapSize || image.SubImageArray[ct].Height <= request.MinimumMipMapSize)
159 int SubImagePerArrayElement = image.SubImageArray.Length / image.ArraySize;
162 pdxImage = Image.New3D(image.Width, image.Height, image.Depth, newMipMapCount, image.Format);
167 for (
int i = 0; i < image.ArraySize; ++i)
169 for (
int j = 0; j < ct; ++j)
171 Utilities.CopyMemory(pdxImage.PixelBuffer[ct2]
.DataPointer, pdxImage.PixelBuffer[j + i * SubImagePerArrayElement]
.DataPointer, pdxImage.PixelBuffer[j + i * SubImagePerArrayElement].BufferStride);
176 catch (AccessViolationException e)
179 Log.Error(
"Failed to export texture with the mipmap minimum size request. ", e);
180 throw new TextureToolsException(
"Failed to export texture with the mipmap minimum size request. ", e);
186 int newMipMapCount = image.MipmapCount;
187 int dataSize = image.DataSize;
188 for (
int i = image.MipmapCount - 1; i > 0; --i)
190 if (image.SubImageArray[i].Width >= request.MinimumMipMapSize || image.SubImageArray[i].Height >= request.MinimumMipMapSize)
194 dataSize -= image.SubImageArray[i].DataSize * image.ArraySize;
198 switch (image.Dimension)
200 case TexImage.TextureDimension.Texture1D:
201 pdxImage = Image.New1D(image.Width, image.MipmapCount, image.Format, image.ArraySize);
break;
202 case TexImage.TextureDimension.Texture2D:
203 pdxImage = Image.New2D(image.Width, image.Height, newMipMapCount, image.Format, image.ArraySize);
break;
204 case TexImage.TextureDimension.TextureCube:
205 pdxImage = Image.NewCube(image.Width, newMipMapCount, image.Format);
break;
207 if (pdxImage == null)
209 Log.Error(
"Image could not be created.");
210 throw new InvalidOperationException(
"Image could not be created.");
213 if (pdxImage.TotalSizeInBytes != dataSize)
215 Log.Error(
"Image size different than expected.");
216 throw new InvalidOperationException(
"Image size different than expected.");
221 int gap = image.MipmapCount - newMipMapCount;
223 for (
int i = 0; i < image.ArraySize * newMipMapCount; ++i)
225 if (i == newMipMapCount || (i > newMipMapCount && (i % newMipMapCount == 0))) j += gap;
226 Utilities.CopyMemory(pdxImage.PixelBuffer[i]
.DataPointer, image.SubImageArray[j].Data, image.SubImageArray[j].DataSize);
230 catch (AccessViolationException e)
233 Log.Error(
"Failed to export texture with the mipmap minimum size request. ", e);
234 throw new TextureToolsException(
"Failed to export texture with the mipmap minimum size request. ", e);
240 switch (image.Dimension)
242 case TexImage.TextureDimension.Texture1D:
243 pdxImage = Image.New1D(image.Width, image.MipmapCount, image.Format, image.ArraySize);
break;
244 case TexImage.TextureDimension.Texture2D:
245 pdxImage = Image.New2D(image.Width, image.Height, image.MipmapCount, image.Format, image.ArraySize);
break;
246 case TexImage.TextureDimension.Texture3D:
247 pdxImage = Image.New3D(image.Width, image.Height, image.Depth, image.MipmapCount, image.Format);
break;
248 case TexImage.TextureDimension.TextureCube:
249 pdxImage = Image.NewCube(image.Width, image.MipmapCount, image.Format);
break;
251 if (pdxImage == null)
253 Log.Error(
"Image could not be created.");
254 throw new InvalidOperationException(
"Image could not be created.");
257 if (pdxImage.TotalSizeInBytes != image.DataSize)
259 Log.Error(
"Image size different than expected.");
260 throw new InvalidOperationException(
"Image size different than expected.");
263 Utilities.CopyMemory(pdxImage.DataPointer, image.Data, image.DataSize);
266 using (var fileStream =
new FileStream(request.FilePath,
FileMode.Create, FileAccess.Write))
268 String extension = Path.GetExtension(request.FilePath);
269 if(extension.Equals(Extension))
271 else if (extension.Equals(
".dds"))
275 Log.Error(
"Unsupported file extension.");
276 throw new TextureToolsException(
"Unsupported file extension.");
281 image.Save(request.FilePath);
297 private void ExportToParadox(TexImage image, ParadoxTextureLibraryData libraryData, ExportToParadoxRequest request)
299 Log.Info(
"Exporting to Paradox Image ...");
301 Image pdxImage = null;
302 switch (image.Dimension)
304 case TexImage.TextureDimension.Texture1D:
305 pdxImage = Image.New1D(image.Width, image.MipmapCount, image.Format, image.ArraySize);
break;
306 case TexImage.TextureDimension.Texture2D:
307 pdxImage = Image.New2D(image.Width, image.Height, image.MipmapCount, image.Format, image.ArraySize);
break;
308 case TexImage.TextureDimension.Texture3D:
309 pdxImage = Image.New3D(image.Width, image.Height, image.Depth, image.MipmapCount, image.Format);
break;
310 case TexImage.TextureDimension.TextureCube:
311 pdxImage = Image.NewCube(image.Width, image.MipmapCount, image.Format);
break;
313 if (pdxImage == null)
315 Log.Error(
"Image could not be created.");
316 throw new InvalidOperationException(
"Image could not be created.");
319 if (pdxImage.TotalSizeInBytes != image.DataSize)
321 Log.Error(
"Image size different than expected.");
322 throw new InvalidOperationException(
"Image size different than expected.");
325 Utilities.CopyMemory(pdxImage.DataPointer, image.Data, image.DataSize);
327 request.PdxImage = pdxImage;
336 private void Load(TexImage image, LoadingRequest request)
338 Log.Info(
"Loading Paradox Image ...");
340 ParadoxTextureLibraryData libraryData =
new ParadoxTextureLibraryData();
341 image.LibraryData[
this] = libraryData;
344 if (request.Mode == LoadingRequest.LoadingMode.PdxImage)
346 inputImage = request.PdxImage;
348 else if (request.Mode == LoadingRequest.LoadingMode.FilePath)
350 using (var fileStream =
new FileStream(request.FilePath,
FileMode.Open, FileAccess.Read))
353 libraryData.PdxImage = inputImage;
357 throw new NotImplementedException();
360 image.Data = inputImage.DataPointer;
362 image.Width = inputImage.Description.Width;
363 image.Height = inputImage.Description.Height;
364 image.Depth = inputImage.Description.Depth;
365 image.Format = inputImage.Description.Format;
366 image.MipmapCount = request.KeepMipMap ? inputImage.Description.MipLevels : 1;
367 image.ArraySize = inputImage.Description.ArraySize;
369 int rowPitch, slicePitch;
370 Tools.ComputePitch(image.Format, image.Width, image.Height, out rowPitch, out slicePitch);
371 image.RowPitch = rowPitch;
372 image.SlicePitch = slicePitch;
374 var bufferStepFactor = request.KeepMipMap ? 1 : inputImage.Description.MipLevels;
375 int imageCount = inputImage.PixelBuffer.Count / bufferStepFactor;
376 image.SubImageArray =
new TexImage.SubImage[imageCount];
378 for (
int i = 0; i < imageCount; ++i)
380 image.SubImageArray[i] =
new TexImage.SubImage();
381 image.SubImageArray[i].Data = inputImage.PixelBuffer[i * bufferStepFactor]
.DataPointer;
382 image.SubImageArray[i].DataSize = inputImage.PixelBuffer[i * bufferStepFactor].BufferStride;
383 image.SubImageArray[i].Width = inputImage.PixelBuffer[i * bufferStepFactor].Width;
384 image.SubImageArray[i].Height = inputImage.PixelBuffer[i * bufferStepFactor].Height;
385 image.SubImageArray[i].RowPitch = inputImage.PixelBuffer[i * bufferStepFactor].RowStride;
386 image.SubImageArray[i].SlicePitch = inputImage.PixelBuffer[i * bufferStepFactor].BufferStride;
387 image.DataSize += image.SubImageArray[i].DataSize;
392 case TextureDimension.Texture1D:
393 image.Dimension = TexImage.TextureDimension.Texture1D;
break;
394 case TextureDimension.Texture2D:
395 image.Dimension = TexImage.TextureDimension.Texture2D;
break;
396 case TextureDimension.Texture3D:
397 image.Dimension = TexImage.TextureDimension.Texture3D;
break;
398 case TextureDimension.TextureCube:
399 image.Dimension = TexImage.TextureDimension.TextureCube;
break;
402 image.DisposingLibrary =
this;
ImageFileType
Image file format used by Image.Save(string,SiliconStudio.Paradox.Graphics.ImageFileType) ...
static Image Load(DataPointer dataBuffer, bool makeACopy=false)
Loads an image from an unmanaged memory pointer.
Provides method to instantiate an image 1D/2D/3D supporting TextureArray and mipmaps on the CPU or to...
System.IO.FileMode FileMode
ImageDescription Description
Description of this image.
Base implementation for ILogger.
Output message to log right away.
TextureDimension Dimension
The dimension of a texture.