public PCCObject(String path) { lzo = new SaltLZOHelper(); fullname = path; BitConverter.IsLittleEndian = true; DebugOutput.PrintLn("Load file : " + path); pccFileName = Path.GetFullPath(path); MemoryTributary tempStream = new MemoryTributary(); if (!File.Exists(pccFileName)) throw new FileNotFoundException("PCC file not found"); using (FileStream fs = new FileStream(pccFileName, FileMode.Open, FileAccess.Read)) { FileInfo tempInfo = new FileInfo(pccFileName); tempStream.WriteFromStream(fs, tempInfo.Length); if (tempStream.Length != tempInfo.Length) { throw new FileLoadException("File not fully read in. Try again later"); } } tempStream.Seek(12, SeekOrigin.Begin); int tempNameSize = tempStream.ReadValueS32(); tempStream.Seek(64 + tempNameSize, SeekOrigin.Begin); int tempGenerator = tempStream.ReadValueS32(); tempStream.Seek(36 + tempGenerator * 12, SeekOrigin.Current); int tempPos = (int)tempStream.Position + 4; tempStream.Seek(0, SeekOrigin.Begin); header = tempStream.ReadBytes(tempPos); tempStream.Seek(0, SeekOrigin.Begin); if (magic != ZBlock.magic && magic.Swap() != ZBlock.magic) { DebugOutput.PrintLn("Magic number incorrect: " + magic); throw new FormatException("This is not a pcc file. The magic number is incorrect."); } if (bCompressed) { DebugOutput.PrintLn("File is compressed"); listsStream = lzo.DecompressPCC(tempStream, this); //Correct the header bCompressed = false; listsStream.Seek(0, SeekOrigin.Begin); listsStream.WriteBytes(header); // Set numblocks to zero listsStream.WriteValueS32(0); //Write the magic number listsStream.WriteBytes(new byte[] { 0xF2, 0x56, 0x1B, 0x4E }); // Write 4 bytes of 0 listsStream.WriteValueS32(0); } else { DebugOutput.PrintLn("File already decompressed. Reading decompressed data."); //listsStream = tempStream; listsStream = new MemoryTributary(); tempStream.WriteTo(listsStream); } tempStream.Dispose(); ReadNames(listsStream); ReadImports(listsStream); ReadExports(listsStream); LoadExports(); }
public void DumpImageData(ImageInfo imgInfo, string archiveDir = null, string fileName = null) { if (fileName == null) fileName = texName + "_" + imgInfo.imgSize + ".bin"; byte[] imgBuffer; switch (imgInfo.storageType) { case storage.pccSto: imgBuffer = new byte[imgInfo.uncSize]; Buffer.BlockCopy(imageData, imgInfo.offset, imgBuffer, 0, imgInfo.uncSize); break; case storage.pccCpr: using (MemoryStream ms = new MemoryStream(imageData)) { SaltLZOHelper lzohelp = new SaltLZOHelper(); imgBuffer = lzohelp.DecompressTex(ms, imgInfo.offset, imgInfo.uncSize, imgInfo.cprSize); } break; case storage.arcCpr: case storage.arcUnc: string archivePath = FindFile(); if (!File.Exists(archivePath)) throw new FileNotFoundException("Texture archive not found in " + archivePath); using (FileStream archiveStream = File.OpenRead(archivePath)) { if (imgInfo.storageType == storage.arcCpr) { SaltLZOHelper lzohelp = new SaltLZOHelper(); imgBuffer = lzohelp.DecompressTex(archiveStream, imgInfo.offset, imgInfo.uncSize, imgInfo.cprSize); } else { archiveStream.Seek(imgInfo.offset, SeekOrigin.Begin); imgBuffer = new byte[imgInfo.uncSize]; archiveStream.Read(imgBuffer, 0, imgBuffer.Length); } } break; default: throw new FormatException("Unsupported texture storage type"); } using (FileStream outputImg = new FileStream(fileName, FileMode.Create, FileAccess.Write)) outputImg.Write(imgBuffer, 0, imgBuffer.Length); }
public void CopyImgList(Texture2D inTex, PCCObject pcc, bool norender = false) { List<ImageInfo> tempList = new List<ImageInfo>(); MemoryStream tempData = new MemoryStream(); SaltLZOHelper lzo = new SaltLZOHelper(); numMipMaps = inTex.numMipMaps; // forced norenderfix // norender = true; int type = -1; if (!norender) { if (imgList.Exists(img => img.storageType == storage.arcCpr) && imgList.Count > 1) type = 1; else if (imgList.Exists(img => img.storageType == storage.pccCpr)) type = 2; else if (imgList.Exists(img => img.storageType == storage.pccSto) || imgList.Count == 1) type = 3; } else type = 3; switch (type) { case 1: for (int i = 0; i < inTex.imgList.Count; i++) { try { ImageInfo newImg = new ImageInfo(); ImageInfo replaceImg = inTex.imgList[i]; Texture2D.storage replaceType = imgList.Find(img => img.imgSize == replaceImg.imgSize).storageType; int j = 0; while (replaceType == storage.empty) { j++; replaceType = imgList[imgList.FindIndex(img => img.imgSize == replaceImg.imgSize) + j].storageType; } if (replaceType == storage.arcCpr || !imgList.Exists(img => img.imgSize == replaceImg.imgSize)) { newImg.storageType = storage.arcCpr; newImg.uncSize = replaceImg.uncSize; newImg.cprSize = replaceImg.cprSize; newImg.imgSize = replaceImg.imgSize; newImg.offset = (int)(replaceImg.offset + inTex.pccOffset + inTex.dataOffset); } else { newImg.storageType = storage.pccSto; newImg.uncSize = replaceImg.uncSize; newImg.cprSize = replaceImg.uncSize; newImg.imgSize = replaceImg.imgSize; newImg.offset = (int)(tempData.Position); using (MemoryStream tempStream = new MemoryStream(inTex.imageData)) { tempData.WriteBytes(lzo.DecompressTex(tempStream, replaceImg.offset, replaceImg.uncSize, replaceImg.cprSize)); } } tempList.Add(newImg); } catch { ImageInfo replaceImg = inTex.imgList[i]; if (!imgList.Exists(img => img.imgSize == replaceImg.imgSize)) throw new Exception("An error occurred during imglist copying and no suitable replacement was found"); ImageInfo newImg = imgList.Find(img => img.imgSize == replaceImg.imgSize); if (newImg.storageType != storage.pccCpr && newImg.storageType != storage.pccSto) throw new Exception("An error occurred during imglist copying and no suitable replacement was found"); int temppos = newImg.offset; newImg.offset = (int)tempData.Position; tempData.Write(imageData, temppos, newImg.cprSize); tempList.Add(newImg); } } break; case 2: for (int i = 0; i < inTex.imgList.Count; i++) { ImageInfo newImg = new ImageInfo(); ImageInfo replaceImg = inTex.imgList[i]; newImg.storageType = storage.pccCpr; newImg.uncSize = replaceImg.uncSize; newImg.cprSize = replaceImg.cprSize; newImg.imgSize = replaceImg.imgSize; newImg.offset = (int)(tempData.Position); byte[] buffer = new byte[newImg.cprSize]; Buffer.BlockCopy(inTex.imageData, replaceImg.offset, buffer, 0, buffer.Length); tempData.WriteBytes(buffer); tempList.Add(newImg); } break; case 3: for (int i = 0; i < inTex.imgList.Count; i++) { ImageInfo newImg = new ImageInfo(); ImageInfo replaceImg = inTex.imgList[i]; newImg.storageType = storage.pccSto; newImg.uncSize = replaceImg.uncSize; newImg.cprSize = replaceImg.uncSize; newImg.imgSize = replaceImg.imgSize; newImg.offset = (int)(tempData.Position); if (replaceImg.storageType == storage.pccCpr) { using (MemoryStream tempStream = new MemoryStream(inTex.imageData)) { tempData.WriteBytes(lzo.DecompressTex(tempStream, replaceImg.offset, replaceImg.uncSize, replaceImg.cprSize)); } } else if (replaceImg.storageType == storage.pccSto) { byte[] buffer = new byte[newImg.cprSize]; Buffer.BlockCopy(inTex.imageData, replaceImg.offset, buffer, 0, buffer.Length); tempData.WriteBytes(buffer); } else throw new NotImplementedException("Copying from non package stored texture no available"); tempList.Add(newImg); } break; default: throw new NotImplementedException(); } for (int i = 0; i < tempList.Count; i++) { ImageInfo tempinfo = tempList[i]; if (inTex.imgList[i].storageType == storage.empty) tempinfo.storageType = storage.empty; tempList[i] = tempinfo; } imgList = tempList; imageData = tempData.ToArray(); tempData.Close(); byte[] buff; //Copy properties using (MemoryStream tempMem = new MemoryStream()) { tempMem.WriteBytes(headerData); for (int i = 0; i < inTex.properties.Count; i++) { SaltPropertyReader.Property prop = inTex.properties.ElementAt(i).Value; if (prop.Name == "UnpackMin") { for (int j = 0; j < inTex.UnpackNum; j++) { tempMem.WriteValueS64(pcc.AddName(prop.Name)); tempMem.WriteValueS64(pcc.AddName(prop.TypeVal.ToString())); tempMem.WriteValueS32(prop.Size); tempMem.WriteValueS32(j); tempMem.WriteValueF32(prop.Value.FloatValue, Endian.Little); } continue; } tempMem.WriteValueS64(pcc.AddName(prop.Name)); if (prop.Name == "None") { for (int j = 0; j < 12; j++) tempMem.WriteByte(0); } else { tempMem.WriteValueS64(pcc.AddName(prop.TypeVal.ToString())); tempMem.WriteValueS64(prop.Size); switch (prop.TypeVal) { case SaltPropertyReader.Type.IntProperty: tempMem.WriteValueS32(prop.Value.IntValue); break; case SaltPropertyReader.Type.BoolProperty: tempMem.Seek(-4, SeekOrigin.Current); tempMem.WriteValueS32(prop.Value.IntValue); tempMem.Seek(4, SeekOrigin.Current); break; case SaltPropertyReader.Type.NameProperty: tempMem.WriteValueS64(pcc.AddName(prop.Value.StringValue)); break; case SaltPropertyReader.Type.StrProperty: tempMem.WriteValueS32(prop.Value.StringValue.Length + 1); foreach (char c in prop.Value.StringValue) tempMem.WriteByte((byte)c); tempMem.WriteByte(0); break; case SaltPropertyReader.Type.StructProperty: tempMem.WriteValueS64(pcc.AddName(prop.Value.StringValue)); foreach (SaltPropertyReader.PropertyValue value in prop.Value.Array) tempMem.WriteValueS32(value.IntValue); break; case SaltPropertyReader.Type.ByteProperty: tempMem.WriteValueS32(pcc.AddName(prop.Value.StringValue)); tempMem.WriteValueS32(prop.Value.IntValue); break; case SaltPropertyReader.Type.FloatProperty: tempMem.WriteValueF32(prop.Value.FloatValue, Endian.Little); break; default: throw new FormatException("unknown property"); } } } buff = tempMem.ToArray(); } int propertiesOffset = SaltPropertyReader.detectStart(pcc, buff); headerData = new byte[propertiesOffset]; Buffer.BlockCopy(buff, 0, headerData, 0, propertiesOffset); properties = new Dictionary<string, SaltPropertyReader.Property>(); List<SaltPropertyReader.Property> tempProperties = SaltPropertyReader.getPropList(pcc, buff); UnpackNum = 0; for (int i = 0; i < tempProperties.Count; i++) { SaltPropertyReader.Property property = tempProperties[i]; if (property.Name == "UnpackMin") UnpackNum++; if (!properties.ContainsKey(property.Name)) properties.Add(property.Name, property); switch (property.Name) { case "Format": texFormat = property.Value.StringValue; break; case "LODGroup": LODGroup = property.Value.StringValue; break; case "CompressionSettings": Compression = property.Value.StringValue; break; case "None": dataOffset = (uint)(property.offsetval + property.Size); break; } } // if "None" property isn't found throws an exception if (dataOffset == 0) throw new Exception("\"None\" property not found"); }
public void addMissingImage(String strImgSize, string fileToReplace) { if (imgList.Count == 1) throw new Exception("The imglist must contain more than 1 texture"); ImageSize imgSize = ImageSize.stringToSize(strImgSize); if (imgList.Exists(img => img.imgSize.width == imgSize.width && img.imgSize.height == imgSize.height)) throw new Exception("The img already exists in the list"); ImageInfo tempImg = imgList.Last(); if (!File.Exists(fileToReplace)) throw new FileNotFoundException("Required file was not found"); ImageFile dds = new DDS(fileToReplace, null); if (dds.imgSize.width != imgSize.width || dds.imgSize.height != imgSize.height) throw new FormatException("Input texture is not required size"); if (dds.format == "R8G8B8") { byte[] buff = ImageMipMapHandler.ConvertTo32bit(dds.imgData, (int)dds.imgSize.width, (int)dds.imgSize.height); dds = new DDS(null, dds.imgSize, "A8R8G8B8", buff); } if (texFormat == "PF_NormalMap_HQ") { if (dds.format != "ATI2") throw new FormatException("Input texture is the wrong format"); } else if (String.Compare(texFormat, "PF_" + dds.format, true) != 0 && String.Compare(texFormat, dds.format, true) != 0) throw new FormatException("Input texture is the wrong format"); ImageInfo newImg = new ImageInfo(); if (tempImg.storageType == storage.empty || tempImg.storageType == storage.arcCpr || tempImg.storageType == storage.arcUnc) throw new FormatException("Existing textures cannot be empty or externally stored"); newImg.storageType = tempImg.storageType; newImg.imgSize = imgSize; using (MemoryStream ms = new MemoryStream()) { ms.WriteBytes(imageData); newImg.offset = (int)ms.Position; switch (newImg.storageType) { case storage.pccSto: ms.WriteBytes(dds.resize()); //newImg.cprSize = dds.imgData.Length; //newImg.uncSize = dds.imgData.Length; newImg.cprSize = dds.resize().Length; newImg.uncSize = dds.resize().Length; break; case storage.pccCpr: SaltLZOHelper lzohelper = new SaltLZOHelper(); //byte[] buff = lzohelper.CompressTex(dds.imgData); byte[] buff = lzohelper.CompressTex(dds.resize()); ms.WriteBytes(buff); //newImg.uncSize = dds.imgData.Length; newImg.uncSize = dds.resize().Length; newImg.cprSize = buff.Length; break; } imageData = ms.ToArray(); } int i = 0; for (; i < imgList.Count; i++) { if (imgList[i].imgSize.width > imgSize.width) continue; imgList.Insert(i, newImg); return; } imgList.Insert(i, newImg); if (ImageMipMapHandler.CprFormat(dds.format) && (newImg.imgSize.width < 4 || newImg.imgSize.height < 4)) { newImg = imgList[i]; if (newImg.imgSize.width < 4 && newImg.imgSize.height > 4) { newImg.imgSize = new ImageSize(4, newImg.imgSize.height); } else if (newImg.imgSize.width > 4 && newImg.imgSize.height < 4) { newImg.imgSize = new ImageSize(newImg.imgSize.width, 4); } else if (newImg.imgSize.width < 4 && newImg.imgSize.height < 4) { newImg.imgSize = new ImageSize(4, 4); } else throw new Exception("safety catch"); imgList[i] = newImg; } //throw new Exception("Newimg wasn't inserted in list!"); }
public void HardReplaceImage(string strImgSize, string fileToReplace) { if (!File.Exists(fileToReplace)) throw new FileNotFoundException("Required file was not found"); ImageFile dds = new DDS(fileToReplace, null); if (strImgSize == null) strImgSize = dds.imgSize.ToString(); if (imgList.Count != 1) throw new Exception("Cannot use this function for a multi-level texture"); ImageSize imgSize = ImageSize.stringToSize(strImgSize); // Check for correct dimensions/ size if (imgSize.width == imgList[0].imgSize.width) { if (imgSize.height != imgList[0].imgSize.height) throw new FormatException("The input size is not the correct dimensions (Error: 0)"); } else if (imgSize.width < imgList[0].imgSize.width) { if (imgList[0].imgSize.width / imgSize.width != imgList[0].imgSize.height / imgSize.height || (imgList[0].imgSize.width / imgSize.width) % 2 != 0) throw new FormatException("The input size is not the correct size (Error: 1)"); } else { if (imgSize.width / imgList[0].imgSize.width != imgSize.height / imgList[0].imgSize.height || (imgSize.width / imgList[0].imgSize.width) % 2 != 0) throw new FormatException("The input size is not the correct size (Error: 2)"); } if (dds.format == "R8G8B8") { byte[] buff = ImageMipMapHandler.ConvertTo32bit(dds.imgData, (int)dds.imgSize.width, (int)dds.imgSize.height); dds = new DDS(null, dds.imgSize, "A8R8G8B8", buff); } if (Class == class2 || Class == class3) ChangeFormat(dds.format); if (texFormat == "PF_NormalMap_HQ") { if (dds.format != "ATI2") throw new FormatException("Input texture is the wrong format"); } else if (String.Compare(texFormat, "PF_" + dds.format, true) != 0 && String.Compare(texFormat, dds.format, true) != 0) throw new FormatException("Input texture is the wrong format"); ImageInfo newImg = new ImageInfo(); newImg.storageType = imgList[0].storageType; if (newImg.storageType == storage.empty || newImg.storageType == storage.arcCpr || newImg.storageType == storage.arcUnc) throw new FormatException("Original texture cannot be empty or externally stored"); newImg.offset = 0; newImg.imgSize = imgSize; switch (newImg.storageType) { case storage.pccSto: imageData = dds.resize(); newImg.cprSize = imageData.Length; newImg.uncSize = imageData.Length; break; case storage.pccCpr: SaltLZOHelper lzohelper = new SaltLZOHelper(); imageData = lzohelper.CompressTex(dds.resize()); newImg.cprSize = imageData.Length; newImg.uncSize = dds.resize().Length; break; } imgList.RemoveAt(0); imgList.Add(newImg); // Fix up properties properties["SizeX"].Value.IntValue = (int)imgSize.width; properties["SizeY"].Value.IntValue = (int)imgSize.height; }
public void replaceImage(string strImgSize, string fileToReplace) { ImageSize imgSize = ImageSize.stringToSize(strImgSize); if (!imgList.Exists(img => img.imgSize == imgSize)) throw new FileNotFoundException("Image with resolution " + imgSize + " isn't found"); int imageIdx = imgList.FindIndex(img => img.imgSize == imgSize); ImageInfo imgInfo = imgList[imageIdx]; if (!File.Exists(fileToReplace)) throw new FileNotFoundException("invalid file to replace: " + fileToReplace); // check if replacing image is supported ImageFile imgFile; string fileFormat = Path.GetExtension(fileToReplace); switch (fileFormat) { case ".dds": imgFile = new DDS(fileToReplace, null); break; case ".DDS": imgFile = new DDS(fileToReplace, null); break; case ".tga": imgFile = new TGA(fileToReplace, null); break; case ".TGA": imgFile = new TGA(fileToReplace, null); break; default: throw new FormatException(fileFormat + " image extension not supported"); } if (imgFile.imgSize.height != imgInfo.imgSize.height || imgFile.imgSize.width != imgInfo.imgSize.width) throw new FormatException("Incorrect input texture dimensions. Expected: " + imgInfo.imgSize.ToString()); // check if images have same format type if (texFormat != imgFile.format && texFormat != ("PF_" + imgFile.format) && imgFile.format != "ATI2") { throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype()); } byte[] imgBuffer; // if the image is empty then recover the archive compression from the image list if (imgInfo.storageType == storage.empty) { imgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType; imgInfo.uncSize = imgFile.resize().Length; imgInfo.cprSize = imgFile.resize().Length; } switch (imgInfo.storageType) { case storage.arcCpr: case storage.arcUnc: throw new NotImplementedException("Texture replacement not supported in external packages yet"); case storage.pccSto: imgBuffer = imgFile.resize(); using (MemoryStream dataStream = new MemoryStream()) { dataStream.WriteBytes(imageData); if (imgBuffer.Length <= imgInfo.uncSize && imgInfo.offset > 0) dataStream.Seek(imgInfo.offset, SeekOrigin.Begin); else imgInfo.offset = (int)dataStream.Position; dataStream.WriteBytes(imgBuffer); imgInfo.cprSize = imgBuffer.Length; imgInfo.uncSize = imgBuffer.Length; imageData = dataStream.ToArray(); } break; case storage.pccCpr: using (MemoryStream dataStream = new MemoryStream()) { dataStream.WriteBytes(imageData); SaltLZOHelper lzohelper = new SaltLZOHelper(); imgBuffer = lzohelper.CompressTex(imgFile.resize()); if (imgBuffer.Length <= imgInfo.cprSize && imgInfo.offset > 0) dataStream.Seek(imgInfo.offset, SeekOrigin.Begin); else imgInfo.offset = (int)dataStream.Position; dataStream.WriteBytes(imgBuffer); imgInfo.cprSize = imgBuffer.Length; imgInfo.uncSize = imgFile.resize().Length; imageData = dataStream.ToArray(); } break; } imgList[imageIdx] = imgInfo; }
public void extractImage(ImageInfo imgInfo, string archiveDir = null, string fileName = null) { ImageFile imgFile; if (fileName == null) fileName = texName + "_" + imgInfo.imgSize + getFileFormat(); byte[] imgBuffer = null; switch (imgInfo.storageType) { case storage.pccSto: imgBuffer = new byte[imgInfo.uncSize]; Buffer.BlockCopy(imageData, imgInfo.offset, imgBuffer, 0, imgInfo.uncSize); break; case storage.arcCpr: case storage.arcUnc: string archivePath = FindFile(); if (String.IsNullOrEmpty(archivePath)) throw new FileNotFoundException(); PCCObject temp = new PCCObject(archivePath); for (int i = 0; i < temp.ExportCount; i++) { if (String.Compare(texName, temp.Exports[i].ObjectName, true) == 0 && temp.Exports[i].ClassName == "Texture2D") { Texture2D temptex = new Texture2D(temp, i); temptex.extractImage(imgInfo.imgSize.ToString(), temp, null, fileName); } } break; case storage.pccCpr: using (MemoryStream ms = new MemoryStream(imageData)) { SaltLZOHelper lzohelp = new SaltLZOHelper(); imgBuffer = lzohelp.DecompressTex(ms, imgInfo.offset, imgInfo.uncSize, imgInfo.cprSize); } break; default: throw new FormatException("Unsupported texture storage type"); } if (imgInfo.storageType == storage.pccSto || imgInfo.storageType == storage.pccCpr) { if (getFileFormat() == ".dds") imgFile = new DDS(fileName, imgInfo.imgSize, texFormat, imgBuffer); else imgFile = new TGA(fileName, imgInfo.imgSize, texFormat, imgBuffer); byte[] saveImg = imgFile.ToArray(); using (FileStream outputImg = new FileStream(imgFile.fileName, FileMode.Create, FileAccess.Write)) outputImg.Write(saveImg, 0, saveImg.Length); } }
public void ReplaceImage(ImageFile ddsfile) { ImageSize imgSize = ddsfile.imgSize; int imageIdx = imgList.FindIndex(img => img.imgSize == imgSize); ImageInfo imgInfo = imgList[imageIdx]; if (imgInfo.storageType == storage.empty && imgInfo.imgSize.width > imgList.First(img => img.storageType != storage.empty).imgSize.width) imgInfo.storageType = imgList.First(img => img.storageType != storage.empty).storageType; else if (imgInfo.storageType == storage.empty) imgInfo.storageType = imgList.Last(img => img.storageType != storage.empty).storageType; if (imgInfo.storageType == storage.arcCpr || imgInfo.storageType == storage.arcUnc) throw new FormatException("Replacement of externally stored textures is not allowed"); else if (imgInfo.storageType == storage.empty) throw new FormatException("Cannot replace images with empty image lists"); byte[] imgBuff = ddsfile.resize(); using (MemoryStream ms = new MemoryStream()) { ms.WriteBytes(imageData); imgInfo.uncSize = imgBuff.Length; if ((long)imgInfo.uncSize != ImageFile.ImageDataSize(ddsfile.imgSize, ddsfile.format, ddsfile.BPP)) throw new FormatException("Input texture not correct length!"); if (imgInfo.storageType == storage.pccCpr) { SaltLZOHelper lzo = new SaltLZOHelper(); imgBuff = lzo.CompressTex(imgBuff); } if (imgBuff.Length <= imgInfo.cprSize && imgInfo.offset > 0) ms.Seek(imgInfo.offset, SeekOrigin.Begin); else imgInfo.offset = (int)ms.Position; imgInfo.cprSize = imgBuff.Length; ms.WriteBytes(imgBuff); imageData = ms.ToArray(); } imgList[imageIdx] = imgInfo; }
public void HardReplaceImage(ImageFile ddsfile) { ImageSize imgSize = ddsfile.imgSize; if (ddsfile.format == "R8G8B8") { byte[] buff = ImageMipMapHandler.ConvertTo32bit(ddsfile.imgData, (int)ddsfile.imgSize.width, (int)ddsfile.imgSize.height); ddsfile = new DDS(null, ddsfile.imgSize, "A8R8G8B8", buff); } ImageInfo newImg = new ImageInfo(); newImg.storageType = imgList[0].storageType; if (newImg.storageType == storage.empty || newImg.storageType == storage.arcCpr || newImg.storageType == storage.arcUnc) throw new FormatException("Original texture cannot be empty or externally stored"); newImg.offset = 0; newImg.imgSize = imgSize; imageData = ddsfile.resize(); newImg.uncSize = imageData.Length; if ((long)newImg.uncSize != ImageFile.ImageDataSize(imgSize, ddsfile.format, ddsfile.BPP)) throw new FormatException("Input texture not correct length!"); switch (newImg.storageType) { case storage.pccSto: newImg.cprSize = imageData.Length; break; case storage.pccCpr: SaltLZOHelper lzohelper = new SaltLZOHelper(); imageData = lzohelper.CompressTex(imageData); newImg.cprSize = imageData.Length; break; } imgList.RemoveAt(0); imgList.Add(newImg); // Fix up properties properties["SizeX"].Value.IntValue = (int)imgSize.width; properties["SizeY"].Value.IntValue = (int)imgSize.height; }
public byte[] DumpImage(ImageSize imgSize) { byte[] imgBuffer = null; ImageInfo imgInfo; if (imgList.Exists(img => (img.imgSize == imgSize && img.cprSize != -1))) imgInfo = imgList.Find(img => img.imgSize == imgSize); else //throw new FileNotFoundException("Image with resolution " + imgSize + " not found"); return null; switch (imgInfo.storageType) { case storage.pccSto: imgBuffer = new byte[imgInfo.uncSize]; Buffer.BlockCopy(imageData, imgInfo.offset, imgBuffer, 0, imgInfo.uncSize); break; case storage.arcCpr: case storage.arcUnc: string archivePath = FindFile(); if (String.IsNullOrEmpty(archivePath)) throw new FileNotFoundException(); PCCObject temp = new PCCObject(archivePath); for (int i = 0; i < temp.ExportCount; i++) { if (String.Compare(texName, temp.Exports[i].ObjectName, true) == 0 && (temp.Exports[i].ClassName == "Texture2D"))// || temp.Exports[i].ClassName == "TextureFlipBook")) { Texture2D temptex = new Texture2D(temp, i); /*if (imgSize.width > dims) { dims = (int) imgSize.width;*/ byte[] temp1 = temptex.DumpImage(imgSize); if (temp1 != null) imgBuffer = temp1; //} } } break; case storage.pccCpr: using (MemoryStream ms = new MemoryStream(imageData)) { SaltLZOHelper lzohelp = new SaltLZOHelper(); imgBuffer = lzohelp.DecompressTex(ms, imgInfo.offset, imgInfo.uncSize, imgInfo.cprSize); } break; default: throw new FormatException("Unsupported texture storage type"); imgBuffer = null; break; } return imgBuffer; }