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 extractImage(ImageInfo imgInfo, string archiveDir = null, string fileName = null) { ImageFile imgFile; if (fileName == null) { fileName = texName + "_" + imgInfo.imgSize + getFileFormat(); } 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.arcCpr: case storage.arcUnc: string archivePath = archiveDir + "\\" + arcName + ".tfc"; if (!File.Exists(archivePath)) { throw new FileNotFoundException("Texture archive not found in " + archivePath); } using (FileStream archiveStream = File.OpenRead(archivePath)) { archiveStream.Seek(imgInfo.offset, SeekOrigin.Begin); if (imgInfo.storageType == storage.arcCpr) { imgBuffer = ZBlock.Decompress(archiveStream, imgInfo.cprSize); } else { imgBuffer = new byte[imgInfo.uncSize]; archiveStream.Read(imgBuffer, 0, imgBuffer.Length); } } break; default: throw new FormatException("Unsupported texture storage type"); } 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(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 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 bool InstallTexture(string texname, List<string> pccs, List<int> IDs, byte[] imgdata) { if (pccs.Count == 0) { DebugOutput.PrintLn("No PCC's found for " + texname + ", skipping."); return false; } string fulpath = pccs[0]; //string temppath = (WhichGame == 1) ? Path.GetDirectoryName(pathBIOGame) : pathBIOGame; // Heff: Again, is the removal of the last dir for ME1 intended, and if so for what purpose? string temppath = pathBIOGame; if (!fulpath.Contains(temppath)) fulpath = Path.Combine(temppath, fulpath); // KFreon: Skip files that don't exist if (!File.Exists(fulpath)) return false; using (PCCObjects.IPCCObject pcc = PCCObjects.Creation.CreatePCCObject(fulpath, WhichGame)) { if ((pcc.Exports[IDs[0]].ClassName != "Texture2D" && pcc.Exports[IDs[0]].ClassName != "LightMapTexture2D" && pcc.Exports[IDs[0]].ClassName != "TextureFlipBook") || String.Compare(pcc.Exports[IDs[0]].ObjectName, texname, true) != 0) throw new InvalidDataException("Export is not correct class or name!"); //Load the texture from the pcc using (Textures.ITexture2D tex2D = pcc.CreateTexture2D(IDs[0], pathBIOGame)) { tex2D.allPccs = pccs; tex2D.expIDs = IDs; int noImg = tex2D.imgList.Count; DebugOutput.PrintLn("Now replacing textures in texture: " + tex2D.texName, true); Debug.WriteLine("Now replacing textures in texture: " + tex2D.texName + " ID: " + IDs[0]); WriteDebug("Now replacing textures in texture: " + tex2D.texName + " ID: " + IDs[0]); ImageFile im = null; try { im = new DDS("", imgdata); } catch { Console.WriteLine("Error: Unable to detect input DDS format, skipping."); return false; } // KFreon: TESTING Debug.WriteLine("First pcc: " + fulpath + " ArcName: " + tex2D.arcName); WriteDebug("First pcc: " + fulpath + " ArcName: " + tex2D.arcName); //The texture is a single image, therefore use replace function if (noImg == 1) { string imgSize = tex2D.imgList[0].imgSize.width.ToString() + "x" + tex2D.imgList[0].imgSize.height.ToString(); try { tex2D.replaceImage(imgSize, im, pathBIOGame); } catch { // KFreon: If replace fails, it's single image thus use the singleimageupscale function tex2D.singleImageUpscale(im, pathBIOGame); } } //If the texture has multiple images, then check the input texture for MIPMAPS else { bool hasMips = true; ImageFile imgFile = im; /*try { ImageMipMapHandler imgMipMap = new ImageMipMapHandler("", imgdata); } catch (Exception e) { hasMips = false; }*/ using (ImageEngineImage img = new ImageEngineImage(imgdata)) hasMips = img.NumMipMaps > 1; if (!hasMips) { string imgSize = imgFile.imgSize.width.ToString() + "x" + imgFile.imgSize.height.ToString(); try { //Try replacing the image. If it doesn't exist then it'll throw and error and you'll need to upscale the image tex2D.replaceImage(imgSize, imgFile, pathBIOGame); } catch (Exception e) { tex2D.addBiggerImage(imgFile, pathBIOGame); } } else { try { tex2D.OneImageToRuleThemAll(imgFile, pathBIOGame, imgdata); } catch (Exception e) { if (e.Message.Contains("Format")) { MessageBox.Show(texname + " is in the wrong format." + Environment.NewLine + Environment.NewLine + e.Message); return false; } } } } Debug.WriteLine("After replace: " + tex2D.arcName); WriteDebug("After replace: " + tex2D.arcName); DebugOutput.PrintLn("Replacement complete. Now saving pcc: " + pcc.pccFileName, true); PCCObjects.IExportEntry expEntry = pcc.Exports[IDs[0]]; expEntry.SetData(tex2D.ToArray(expEntry.DataOffset, pcc)); expEntry.hasChanged = true; pcc.Exports[IDs[0]] = expEntry; pcc.saveToFile(pcc.pccFileName); int modCount = tex2D.allPccs.Count; // KFreon: Elapsed time stuff int start = Environment.TickCount; if (modCount > 1) for (int item = 1; item < modCount; item++) { Debug.WriteLine(pccs[item] + " " + IDs[item]); WriteDebug(pccs[item] + " " + IDs[item]); if (!SaveFile(pccs, IDs, tex2D, item)) break; } Debug.WriteLine(""); WriteDebug(""); // KFreon: More timer stuff TimeSpan ts = TimeSpan.FromMilliseconds(Environment.TickCount - start); Console.WriteLine(ts.Duration().ToString()); DebugOutput.Print("All PCC updates finished. "); return true; } } }
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 ImageMipMapHandler(string imageWithMipMaps, byte[] data) { imageWithMipMaps = (imageWithMipMaps == "") ? ".dds" : imageWithMipMaps; imageList = new List <ImageFile>(); string fileFormat = Path.GetExtension(imageWithMipMaps).ToLowerInvariant(); string fileName = Path.GetFileNameWithoutExtension(imageWithMipMaps); ImageFile imageMipMap; int headerSize; if (data != null) { headerSize = 128; imageMipMap = new DDS("", data); } else { switch (fileFormat) { case ".dds": headerSize = 128; imageMipMap = new DDS(imageWithMipMaps, null); break; case ".tga": headerSize = 18; imageMipMap = new TGA(imageWithMipMaps, null); break; default: throw new FormatException("Invalid image format"); } } //Console.WriteLine("Image Format: {0}", imageMipMap.format); //check if image has mipmaps /* using (FileStream imageStream = File.OpenRead(imageWithMipMaps)) * { * long size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP); * if (imageStream.Length - headerSize != ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP)) * { * //MessageBox.Show("bytes in file: " + (imageStream.Length - headerSize) + ", bytes calulated: " + ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP) + ", BPP: " + imageMipMap.BPP + ", format: " + imageMipMap.format); * //Console.WriteLine("bytes in file: {0}, bytes calulated: {1}, BPP: {2}", imageStream.Length - headerSize, ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP), imageMipMap.BPP); * throw new FormatException("The image doesn't have any mipmaps"); * } * } */ // KFreon: This can be wrong too much. Single mip images etc. /* * var size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP); * if (imageMipMap.imgData.Length != size) * throw new FormatException("The image doesn't have any mipmaps");*/ byte[] buffer = null; // add the first tga image if (fileFormat == ".tga") { //buffer = new byte[imageMipMap.imgData.Length]; buffer = imageMipMap.imgData; //imageList.Add(imageMipMap); } // Heff: Use Max to support 1x1 mips for 1:2 ratio images. int maxCount = (int)Math.Max(imageMipMap.imgSize.width, imageMipMap.imgSize.height); int count = 1; int imgDataPos = 0; while (count <= maxCount) { ImageFile newImageFile; ImageSize newImageSize = imageMipMap.imgSize / count; //if (newImageSize.width < 4 || newImageSize.height < 4) // break; int imgDataSize = (int)ImageDataSize(newImageSize, imageMipMap.format, imageMipMap.BPP); if (fileFormat == ".dds") { buffer = new byte[imgDataSize]; Buffer.BlockCopy(imageMipMap.imgData, imgDataPos, buffer, 0, imgDataSize); imgDataPos += imgDataSize; if (imageMipMap.format == "R8G8B8") // Automatic conversion to 32-bit { buffer = ConvertTo32bit(buffer, (int)newImageSize.width, (int)newImageSize.height); newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, "A8R8G8B8", buffer); } else { newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer); } } else if (fileFormat == ".tga") { newImageFile = new TGA(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer); if (newImageSize != new ImageSize(1, 1)) { buffer = ShrinkImage(buffer, newImageSize, imageMipMap.BPP); } } else { throw new FormatException("Invalid image format"); } imageList.Add(newImageFile); count *= 2; } }
public ImageMipMapHandler(string imageWithMipMaps, byte[] data) { imageWithMipMaps = (imageWithMipMaps == "") ? ".dds" : imageWithMipMaps; imageList = new List<ImageFile>(); string fileFormat = Path.GetExtension(imageWithMipMaps).ToLowerInvariant(); string fileName = Path.GetFileNameWithoutExtension(imageWithMipMaps); ImageFile imageMipMap; int headerSize; if (data != null) { headerSize = 128; imageMipMap = new DDS("", data); } else { switch (fileFormat) { case ".dds": headerSize = 128; imageMipMap = new DDS(imageWithMipMaps, null); break; case ".tga": headerSize = 18; imageMipMap = new TGA(imageWithMipMaps, null); break; default: throw new FormatException("Invalid image format"); } } //Console.WriteLine("Image Format: {0}", imageMipMap.format); //check if image has mipmaps /* using (FileStream imageStream = File.OpenRead(imageWithMipMaps)) { long size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP); if (imageStream.Length - headerSize != ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP)) { //MessageBox.Show("bytes in file: " + (imageStream.Length - headerSize) + ", bytes calulated: " + ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP) + ", BPP: " + imageMipMap.BPP + ", format: " + imageMipMap.format); //Console.WriteLine("bytes in file: {0}, bytes calulated: {1}, BPP: {2}", imageStream.Length - headerSize, ImageMipMapDataSize(imageMipMap.imgSize, imageMipMap.format, imageMipMap.BPP), imageMipMap.BPP); throw new FormatException("The image doesn't have any mipmaps"); } } */ var size = ImageMipMapDataSize(imageMipMap.imgSize, CprFormat(imageMipMap.format), imageMipMap.BPP); if (imageMipMap.imgData.Length != size) throw new FormatException("The image doesn't have any mipmaps"); byte[] buffer = null; // add the first tga image if (fileFormat == ".tga") { //buffer = new byte[imageMipMap.imgData.Length]; buffer = imageMipMap.imgData; //imageList.Add(imageMipMap); } // Heff: Use Max to support 1x1 mips for 1:2 ratio images. int maxCount = (int)Math.Max(imageMipMap.imgSize.width, imageMipMap.imgSize.height); int count = 1; int imgDataPos = 0; while (count <= maxCount) { ImageFile newImageFile; ImageSize newImageSize = imageMipMap.imgSize / count; //if (newImageSize.width < 4 || newImageSize.height < 4) // break; int imgDataSize = (int)ImageDataSize(newImageSize, imageMipMap.format, imageMipMap.BPP); if (fileFormat == ".dds") { buffer = new byte[imgDataSize]; Buffer.BlockCopy(imageMipMap.imgData, imgDataPos, buffer, 0, imgDataSize); imgDataPos += imgDataSize; if (imageMipMap.format == "R8G8B8") // Automatic conversion to 32-bit { buffer = ConvertTo32bit(buffer, (int)newImageSize.width, (int)newImageSize.height); newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, "A8R8G8B8", buffer); } else newImageFile = new DDS(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer); } else if (fileFormat == ".tga") { newImageFile = new TGA(fileName + "_" + newImageSize + fileFormat, newImageSize, imageMipMap.format, buffer); if (newImageSize != new ImageSize(1, 1)) buffer = ShrinkImage(buffer, newImageSize, imageMipMap.BPP); } else throw new FormatException("Invalid image format"); imageList.Add(newImageFile); count *= 2; } }
/// <summary> /// Load an image into one of AK86's classes. /// </summary> /// <param name="im">AK86 image already, just return it unless null. Then load from fileToLoad.</param> /// <param name="fileToLoad">Path to file to be loaded. Irrelevent if im is provided.</param> /// <returns>AK86 Image file.</returns> public static ImageFile LoadAKImageFile(ImageFile im, string fileToLoad) { ImageFile imgFile = null; if (im != null) imgFile = im; else { if (!File.Exists(fileToLoad)) throw new FileNotFoundException("invalid file to replace: " + fileToLoad); // check if replacing image is supported string fileFormat = Path.GetExtension(fileToLoad); switch (fileFormat) { case ".dds": imgFile = new DDS(fileToLoad, null); break; case ".tga": imgFile = new TGA(fileToLoad, null); break; default: throw new FileNotFoundException(fileFormat + " image extension not supported"); } } return imgFile; }
public void addBiggerImage(ImageFile im) { ImageSize biggerImageSizeOnList = privateimgList.Max(image => image.imgSize); // check if replacing image is supported ImageFile imgFile = im; if (imgFile.format == "R8G8B8") { byte[] buff = ImageMipMapHandler.ConvertTo32bit(imgFile.imgData, (int)imgFile.imgSize.width, (int)imgFile.imgSize.height); imgFile = new DDS(null, imgFile.imgSize, "A8R8G8B8", buff); } if (!Methods.CheckTextureFormat(texFormat, imgFile.format)) throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype()); // check if image to add is valid if (biggerImageSizeOnList.width * 2 != imgFile.imgSize.width || biggerImageSizeOnList.height * 2 != imgFile.imgSize.height) throw new FormatException("image size " + imgFile.imgSize + " isn't valid, must be " + new ImageSize(biggerImageSizeOnList.width * 2, biggerImageSizeOnList.height * 2)); // this check avoids insertion inside textures that have only 1 image stored inside pcc //if (!imgList.Exists(img => img.storageType != storage.empty && img.storageType != storage.pccSto)) // throw new Exception("Unable to add image, texture must have a reference to an external archive"); if (privateimgList.Count <= 1) throw new Exception("Unable to add image, texture must have more than one image present"); // !!! warning, this method breaks consistency between imgList and imageData[] !!! ImageInfo newImgInfo = new ImageInfo(); newImgInfo.storageType = privateimgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType; newImgInfo.imgSize = imgFile.imgSize; newImgInfo.uncSize = imgFile.resize().Length; newImgInfo.cprSize = 0x00; // not yet filled newImgInfo.offset = 0x00; // not yet filled privateimgList.Insert(0, newImgInfo); // insert new image on top of the list //now I let believe the program that I'm doing an image replace, saving lot of code ;) replaceImage(newImgInfo.imgSize.ToString(), im); //updating num of images numMipMaps++; // update MipTailBaseIdx //SaltPropertyReader.Property MipTail = properties["MipTailBaseIdx"]; int propVal = properties["MipTailBaseIdx"].Value.IntValue; propVal++; properties["MipTailBaseIdx"].Value.IntValue = propVal; //MessageBox.Show("raw size: " + properties["MipTailBaseIdx"].raw.Length + "\nproperty offset: " + properties["MipTailBaseIdx"].offsetval); using (MemoryStream rawStream = new MemoryStream(properties["MipTailBaseIdx"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["MipTailBaseIdx"].raw = rawStream.ToArray(); } //properties["MipTailBaseIdx"] = MipTail; // update Sizes //SaltPropertyReader.Property Size = properties["SizeX"]; propVal = (int)newImgInfo.imgSize.width; properties["SizeX"].Value.IntValue = propVal; using (MemoryStream rawStream = new MemoryStream(properties["SizeX"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["SizeX"].raw = rawStream.ToArray(); } //properties["SizeX"] = Size; //Size = properties["SizeY"]; properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height; using (MemoryStream rawStream = new MemoryStream(properties["SizeY"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["SizeY"].raw = rawStream.ToArray(); } //properties["SizeY"] = Size; //this.hasChanged = true; }
public void replaceImage2(string strImgSize, string fileToReplace, string archiveDir) { 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; default: throw new FormatException(fileFormat + " image extension not supported"); } if (texFormat == "PF_NormalMap_HQ") { if (imgFile.format != "ATI2") throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype()); } else if (String.Compare(texFormat, "PF_" + imgFile.format, true) != 0 && String.Compare(texFormat, imgFile.format, true) != 0) { 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: string archivePath = FullArcPath; if (String.IsNullOrEmpty(archivePath)) archivePath = GetTexArchive(archiveDir); if (!File.Exists(archivePath)) throw new FileNotFoundException("Texture archive not found in " + archivePath); imgBuffer = imgFile.imgData; if (imgBuffer.Length != imgInfo.uncSize) throw new FormatException("image sizes do not match, original is " + imgInfo.uncSize + ", new is " + imgBuffer.Length); if (arcName.Length <= CustCache.Length || arcName.Substring(0, CustCache.Length) != CustCache) // Check whether existing texture is in a custom cache { ChooseNewCache(archiveDir, imgBuffer.Length); archivePath = FullArcPath; } else { FileInfo arc = new FileInfo(archivePath); if (arc.Length + imgBuffer.Length >= 0x80000000) { ChooseNewCache(archiveDir, imgBuffer.Length); archivePath = FullArcPath; } } using (FileStream archiveStream = new FileStream(archivePath, FileMode.Append, FileAccess.Write)) { int newOffset = (int)archiveStream.Position; if (imgInfo.storageType == storage.arcCpr) { byte[] tempBuff; SaltLZOHelper lzohelper = new SaltLZOHelper(); tempBuff = lzohelper.CompressTex(imgBuffer); imgBuffer = new byte[tempBuff.Length]; Buffer.BlockCopy(tempBuff, 0, imgBuffer, 0, tempBuff.Length); imgInfo.cprSize = imgBuffer.Length; } archiveStream.Write(imgBuffer, 0, imgBuffer.Length); imgInfo.offset = newOffset; } break; 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; } imgList[imageIdx] = imgInfo; }
public void singleImageUpscale(string imagePathToAdd, string archiveDir) { ImageSize biggerImageSizeOnList = imgList.Max(image => image.imgSize); // check if replacing image is supported ImageFile imgFile; string fileFormat = Path.GetExtension(imagePathToAdd); switch (fileFormat) { case ".dds": imgFile = new DDS(imagePathToAdd, null); break; case ".DDS": imgFile = new DDS(imagePathToAdd, null); break; default: throw new FormatException(fileFormat + " image extension not supported"); } if (texFormat == "PF_NormalMap_HQ") { if (imgFile.format != "ATI2") throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype()); } else if (String.Compare(texFormat, "PF_" + imgFile.format, true) != 0 && String.Compare(texFormat, imgFile.format, true) != 0) { throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype()); } // !!! warning, this method breaks consistency between imgList and imageData[] !!! ImageInfo newImgInfo = new ImageInfo(); newImgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType; newImgInfo.imgSize = imgFile.imgSize; newImgInfo.uncSize = imgFile.resize().Length; newImgInfo.cprSize = 0x00; // not yet filled newImgInfo.offset = 0x00; // not yet filled imgList.RemoveAt(0); // Remove old single image and add new one imgList.Add(newImgInfo); //now I let believe the program that I'm doing an image replace, saving lot of code ;) replaceImage2(newImgInfo.imgSize.ToString(), imagePathToAdd, archiveDir); // update Sizes properties["SizeX"].Value.IntValue = (int)newImgInfo.imgSize.width; properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height; }
public void addBiggerImage(string imagePathToAdd, string archiveDir) { ImageSize biggerImageSizeOnList = imgList.Max(image => image.imgSize); // check if replacing image is supported ImageFile imgFile; string fileFormat = Path.GetExtension(imagePathToAdd); switch (fileFormat) { case ".dds": imgFile = new DDS(imagePathToAdd, null); break; case ".DDS": imgFile = new DDS(imagePathToAdd, null); break; default: throw new FormatException(fileFormat + " image extension not supported"); } if (texFormat == "PF_NormalMap_HQ") { if (imgFile.format != "ATI2") throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype()); } else if (String.Compare(texFormat, "PF_" + imgFile.format, true) != 0 && String.Compare(texFormat, imgFile.format, true) != 0) { throw new FormatException("Different image format, original is " + texFormat + ", new is " + imgFile.subtype()); } // check if image to add is valid if (biggerImageSizeOnList.width * 2 != imgFile.imgSize.width || biggerImageSizeOnList.height * 2 != imgFile.imgSize.height) throw new FormatException("image size " + imgFile.imgSize + " isn't valid, must be " + new ImageSize(biggerImageSizeOnList.width * 2, biggerImageSizeOnList.height * 2)); if (imgList.Count <= 1) throw new Exception("Unable to add image, texture must have more than one image present"); // !!! warning, this method breaks consistency between imgList and imageData[] !!! ImageInfo newImgInfo = new ImageInfo(); newImgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType; // for additional mipmaps keep them in external archive but only when // texture allready have such property if (properties.ContainsKey("TextureFileCacheName")) newImgInfo.storageType = storage.arcCpr; newImgInfo.imgSize = imgFile.imgSize; newImgInfo.uncSize = imgFile.resize().Length; newImgInfo.cprSize = 0x00; // not yet filled newImgInfo.offset = 0x00; // not yet filled imgList.Insert(0, newImgInfo); // insert new image on top of the list //now I let believe the program that I'm doing an image replace, saving lot of code ;) replaceImage(newImgInfo.imgSize.ToString(), imagePathToAdd, archiveDir); //updating num of images numMipMaps++; // update MipTailBaseIdx int propVal = properties["MipTailBaseIdx"].Value.IntValue; propVal++; properties["MipTailBaseIdx"].Value.IntValue = propVal; // update Sizes properties["SizeX"].Value.IntValue = (int)newImgInfo.imgSize.width; properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height; }
public void replaceImage(string strImgSize, string fileToReplace, string archiveDir) { 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 ".tga": imgFile = new TGA(fileToReplace, null); break; default: throw new FileFormatException(fileFormat + " image extension not supported"); } // check if images have same format type if (texFormat != imgFile.format) { DialogResult selection = MessageBox.Show("Warning, replacing image has format " + imgFile.subtype() + " while original has " + texFormat + ", would you like to replace it anyway?", "Warning, different image format found", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (selection == DialogResult.Yes) imgFile.format = texFormat; else return; //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: string archivePath = archiveDir + "\\" + arcName + ".tfc"; if (!File.Exists(archivePath)) throw new FileNotFoundException("Texture archive not found in " + archivePath); if (getFileFormat() == ".tga") imgBuffer = imgFile.resize(); // shrink image to essential data else imgBuffer = imgFile.imgData; if (imgBuffer.Length != imgInfo.uncSize) throw new FormatException("image sizes do not match, original is " + imgInfo.uncSize + ", new is " + imgBuffer.Length); using (FileStream archiveStream = new FileStream(archivePath, FileMode.Append, FileAccess.Write)) { int newOffset = (int)archiveStream.Position; if (imgInfo.storageType == storage.arcCpr) { imgBuffer = ZBlock.Compress(imgBuffer); /*byte[] compressed = ZBlock.Compress(imgBuffer); archiveStream.Write(compressed, 0, compressed.Length);*/ imgInfo.cprSize = imgBuffer.Length; } //else archiveStream.Write(imgBuffer, 0, imgBuffer.Length); imgInfo.offset = newOffset; } break; case storage.pccSto: imgBuffer = imgFile.imgData; // copy image data as-is if (imgBuffer.Length != imgInfo.uncSize) throw new FormatException("image sizes do not match, original is " + imgInfo.uncSize + ", new is " + imgBuffer.Length); using (MemoryStream dataStream = new MemoryStream(imageData)) { dataStream.Seek(imgInfo.offset, SeekOrigin.Begin); dataStream.Write(imgBuffer, 0, imgBuffer.Length); } break; } imgList[imageIdx] = imgInfo; }
// New methods! public void OneSizeFitsAll(String inputFile, bool resFix = false) { // forced lowresfix // resFix = true; if (!File.Exists(inputFile)) throw new FileNotFoundException("Input texture not found at: " + inputFile); bool containsmips = true; ImageMipMapHandler mipmaps = null; if (imgList.Count > 1) { try{ mipmaps = new ImageMipMapHandler(inputFile, null); } catch (FormatException) { containsmips = false; } } else containsmips = false; ImageInfo existingImg = imgList.First(img => img.storageType != storage.empty); if (containsmips) { if ((float)mipmaps.imageList[0].imgSize.width / (float)mipmaps.imageList[0].imgSize.height != (float)existingImg.imgSize.width / (float)existingImg.imgSize.height) throw new FormatException("Input texture not correct aspect ratio"); if (mipmaps.imageList[0].format == "PF_R8G8B8") // Convert to 32-bit if necessary { for (int i = 0; i < mipmaps.imageList.Count; i++) mipmaps.imageList[i] = new DDS(null, mipmaps.imageList[i].imgSize, "A8R8G8B8", ImageMipMapHandler.ConvertTo32bit(mipmaps.imageList[i].resize(), (int)mipmaps.imageList[i].imgSize.width, (int)mipmaps.imageList[i].imgSize.height)); } if (Class == class2 || Class == class3) // Allow format modification if one of the derived classes. Don't need the single level check since we're replacing all levels ChangeFormat(mipmaps.imageList[0].format); if (texFormat == "PF_NormalMap_HQ") // Check formats { if (mipmaps.imageList[0].format != "ATI2") throw new FormatException("Texture not in correct format - Expected ATI2"); } else if (String.Compare(texFormat, "PF_" + mipmaps.imageList[0].format, true) != 0) throw new FormatException("Texture not in correct format - Expected " + texFormat); for (int i = mipmaps.imageList.Count - 1; i >= 0; i--) { if (imgList.Exists(img => img.imgSize == mipmaps.imageList[i].imgSize)) ReplaceImage(mipmaps.imageList[i]); else if (mipmaps.imageList[i].imgSize.width > imgList.First().imgSize.width && mipmaps.imageList[i].imgSize.height > imgList.First().imgSize.height) UpscaleImage(mipmaps.imageList[i]); //else // AddMissingImage(mipmaps.imageList[i]); // Else ignore missing values } while (imgList[0].imgSize.width > mipmaps.imageList[0].imgSize.width) // Remove any existing higher levels imgList.RemoveAt(0); } else { ImageFile ddsfile = new DDS(inputFile, null); if ((float)ddsfile.imgSize.width / (float)ddsfile.imgSize.height != (float)existingImg.imgSize.width / (float)existingImg.imgSize.height) // Check dimensions throw new FormatException("Input texture not correct aspect ratio"); if (ddsfile.format == "R8G8B8") ddsfile = new DDS(null, ddsfile.imgSize, "A8R8G8B8", ImageMipMapHandler.ConvertTo32bit(ddsfile.resize(), (int)ddsfile.imgSize.width, (int)ddsfile.imgSize.height)); if (imgList.Count == 1 && (Class == class2 || Class == class3)) // Since this is single level replacement, only allow format change if a single level texture with required class ChangeFormat(ddsfile.format); if (texFormat == "PF_NormalMap_HQ") // Check format { if (ddsfile.format != "ATI2") throw new FormatException("Texture not in correct format - Expected ATI2"); } else if (String.Compare(texFormat, "PF_" + ddsfile.format, true) != 0) throw new FormatException("Texture not in correct format - Expected " + texFormat); if (imgList.Count == 1 && imgList[0].imgSize != ddsfile.imgSize) // If img doesn't exist and it's a single level texture, use hard replace HardReplaceImage(ddsfile); else if (imgList.Exists(img => img.imgSize == ddsfile.imgSize)) // Catches the rest of the single levels and every one which has an existing reference for that level ReplaceImage(ddsfile); else if (ddsfile.imgSize.width > imgList[0].imgSize.width) // Add a greater image UpscaleImage(ddsfile); //else if (ddsfile.imgSize.width < imgList.Last().imgSize.width) // Add a smaller image // AddMissingImage(ddsfile); } if (imgList.Count > 1 && resFix) LowResFix(); // Fix up properties if (properties.ContainsKey("SizeX")) properties["SizeX"].Value.IntValue = (int)imgList.First(img => img.storageType != storage.empty).imgSize.width; if (properties.ContainsKey("SizeY")) properties["SizeY"].Value.IntValue = (int)imgList.First(img => img.storageType != storage.empty).imgSize.height; if (properties.ContainsKey("MipTailBaseIdx")) properties["MipTailBaseIdx"].Value.IntValue = imgList.Count - 1; numMipMaps = (uint)imgList.Count; }
public void addBiggerImage(string imagePathToAdd, string archiveDir) { ImageSize biggerImageSizeOnList = imgList.Max(image => image.imgSize); // check if replacing image is supported ImageFile imgFile; string fileFormat = Path.GetExtension(imagePathToAdd); switch (fileFormat) { case ".dds": imgFile = new DDS(imagePathToAdd, null); break; case ".tga": imgFile = new TGA(imagePathToAdd, null); break; default: throw new FileFormatException(fileFormat + " image extension not supported"); } // check if image to add is valid if(biggerImageSizeOnList.width * 2 != imgFile.imgSize.width || biggerImageSizeOnList.height * 2 != imgFile.imgSize.height) throw new FormatException("image size " + imgFile.imgSize + " isn't valid, must be " + new ImageSize(biggerImageSizeOnList.width * 2,biggerImageSizeOnList.height * 2)); // this check avoids insertion inside textures that have only 1 image stored inside pcc if(!imgList.Exists(img => img.storageType != storage.empty && img.storageType != storage.pccSto)) throw new Exception("Unable to add image, texture must have a reference to an external archive"); // !!! warning, this method breaks consistency between imgList and imageData[] !!! ImageInfo newImgInfo = new ImageInfo(); newImgInfo.storageType = imgList.Find(img => img.storageType != storage.empty && img.storageType != storage.pccSto).storageType; newImgInfo.imgSize = imgFile.imgSize; newImgInfo.uncSize = imgFile.resize().Length; newImgInfo.cprSize = 0x00; // not yet filled newImgInfo.offset = 0x00; // not yet filled imgList.Insert(0, newImgInfo); // insert new image on top of the list //now I let believe the program that I'm doing an image replace, saving lot of code ;) replaceImage(newImgInfo.imgSize.ToString(), imagePathToAdd, archiveDir); //updating num of images numMipMaps++; // update MipTailBaseIdx //PropertyReader.Property MipTail = properties["MipTailBaseIdx"]; int propVal = properties["MipTailBaseIdx"].Value.IntValue; propVal++; properties["MipTailBaseIdx"].Value.IntValue = propVal; //MessageBox.Show("raw size: " + properties["MipTailBaseIdx"].raw.Length + "\nproperty offset: " + properties["MipTailBaseIdx"].offsetval); using (MemoryStream rawStream = new MemoryStream(properties["MipTailBaseIdx"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["MipTailBaseIdx"].raw = rawStream.ToArray(); } //properties["MipTailBaseIdx"] = MipTail; // update Sizes //PropertyReader.Property Size = properties["SizeX"]; propVal = (int)newImgInfo.imgSize.width; properties["SizeX"].Value.IntValue = propVal; using (MemoryStream rawStream = new MemoryStream(properties["SizeX"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["SizeX"].raw = rawStream.ToArray(); } //properties["SizeX"] = Size; //Size = properties["SizeY"]; properties["SizeY"].Value.IntValue = (int)newImgInfo.imgSize.height; using (MemoryStream rawStream = new MemoryStream(properties["SizeY"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["SizeY"].raw = rawStream.ToArray(); } //properties["SizeY"] = Size; properties["OriginalSizeX"].Value.IntValue = propVal; using (MemoryStream rawStream = new MemoryStream(properties["OriginalSizeX"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["OriginalSizeX"].raw = rawStream.ToArray(); } properties["OriginalSizeY"].Value.IntValue = propVal; using (MemoryStream rawStream = new MemoryStream(properties["OriginalSizeY"].raw)) { rawStream.Seek(rawStream.Length - 4, SeekOrigin.Begin); rawStream.WriteValueS32(propVal); properties["OriginalSizeY"].raw = rawStream.ToArray(); } }
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[] extractImage(ImageInfo imgInfo, bool NoOutput, string archiveDir = null, string fileName = null) { ImageFile imgFile; if (fileName == null) { fileName = texName + "_" + imgInfo.imgSize + getFileFormat(); } 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.arcCpr: case storage.arcUnc: //string archivePath = GetTexArchive(archiveDir); string archivePath = FullArcPath; if (String.IsNullOrEmpty(archivePath)) GetTexArchive(archiveDir); if (archivePath == null) throw new FileNotFoundException("Texture archive not found!"); if (!File.Exists(archivePath)) throw new FileNotFoundException("Texture archive not found in " + archivePath); using (FileStream archiveStream = File.OpenRead(archivePath)) { archiveStream.Seek(imgInfo.offset, SeekOrigin.Begin); if (imgInfo.storageType == storage.arcCpr) imgBuffer = ZBlock.Decompress(archiveStream, imgInfo.cprSize); else { imgBuffer = new byte[imgInfo.uncSize]; archiveStream.Read(imgBuffer, 0, imgBuffer.Length); } } break; default: throw new FormatException("Unsupported texture storage type"); } //if (getFileFormat() == ".dds") imgFile = new DDS(fileName, imgInfo.imgSize, Textures.Methods.StringifyFormat(texFormat), imgBuffer); //else // imgFile = new TGA(fileName, imgInfo.imgSize, texFormat, imgBuffer); byte[] saveImg = imgFile.ToArray(); if (!NoOutput) using (FileStream outputImg = new FileStream(imgFile.fileName, FileMode.Create, FileAccess.Write)) outputImg.Write(saveImg, 0, saveImg.Length); return saveImg; }
public void InstallTexture(string texname, List<string> pccs, List<int> IDs, byte[] imgdata) { string fulpath = pccs[0]; string temppath = (WhichGame == 1) ? Path.GetDirectoryName(pathBIOGame) : pathBIOGame; if (!fulpath.Contains(temppath)) fulpath = Path.Combine(temppath, fulpath); // KFreon: Skip files that don't exist if (!File.Exists(fulpath)) return; PCCObjects.IPCCObject pcc = PCCObjects.Creation.CreatePCCObject(fulpath, WhichGame); if ((pcc.Exports[IDs[0]].ClassName != "Texture2D" && pcc.Exports[IDs[0]].ClassName != "LightMapTexture2D" && pcc.Exports[IDs[0]].ClassName != "TextureFlipBook") || String.Compare(pcc.Exports[IDs[0]].ObjectName, texname, true) != 0) throw new InvalidDataException("Export is not correct class or name!"); //Load the texture from the pcc Textures.ITexture2D tex2D = null; tex2D = pcc.CreateTexture2D(IDs[0], pathBIOGame); tex2D.allPccs = pccs; tex2D.expIDs = IDs; int noImg = tex2D.imgList.Count; DebugOutput.PrintLn("Now replacing textures in texture: " + tex2D.texName, true); Debug.WriteLine("Now replacing textures in texture: " + tex2D.texName + " ID: " + IDs[0]); WriteDebug("Now replacing textures in texture: " + tex2D.texName + " ID: " + IDs[0]); ImageFile im = null; try { im = new DDS("", imgdata); } catch { Console.WriteLine(""); } // KFreon: TESTING Debug.WriteLine("First pcc: " + fulpath + " ArcName: " + tex2D.arcName); WriteDebug("First pcc: " + fulpath + " ArcName: " + tex2D.arcName); //The texture is a single image, therefore use replace function if (noImg == 1) { string imgSize = tex2D.imgList[0].imgSize.width.ToString() + "x" + tex2D.imgList[0].imgSize.height.ToString(); try { tex2D.replaceImage(imgSize, im, pathBIOGame); } catch { // KFreon: If replace fails, it's single image thus use the singleimageupscale function tex2D.singleImageUpscale(im, pathBIOGame); } } //If the texture has multiple images, then check the input texture for MIPMAPS else { bool hasMips = true; ImageFile imgFile = im; try { ImageMipMapHandler imgMipMap = new ImageMipMapHandler("", imgdata); } catch { hasMips = false; } if (!hasMips) { //string fileformat = Path.GetExtension(texFile); //imgFile = new DDS(texFile); string imgSize = imgFile.imgSize.width.ToString() + "x" + imgFile.imgSize.height.ToString(); try { //Try replacing the image. If it doesn't exist then it'll throw and error and you'll need to upscale the image tex2D.replaceImage(imgSize, imgFile, pathBIOGame); } catch { tex2D.addBiggerImage(imgFile, pathBIOGame); } } else { try { tex2D.OneImageToRuleThemAll(imgFile, pathBIOGame, imgdata); } catch (Exception e) { if (e.Message.Contains("Format")) { MessageBox.Show(texname + " is in the wrong format." + Environment.NewLine + Environment.NewLine + e.Message); return; } } } } Debug.WriteLine("After replace: " + tex2D.arcName); WriteDebug("After replace: " + tex2D.arcName); DebugOutput.PrintLn("Replacement complete. Now saving pcc: " + pcc.pccFileName, true); //tex2D.DumpTexture(@"R:\commit.txt"); PCCObjects.IExportEntry expEntry = pcc.Exports[IDs[0]]; expEntry.SetData(tex2D.ToArray(expEntry.DataOffset, pcc)); expEntry.hasChanged = true; pcc.Exports[IDs[0]] = expEntry; pcc.saveToFile(pcc.pccFileName); /*File.Delete(loc + "tex.dds"); File.Delete(loc + "data.bin");*/ int modCount = tex2D.allPccs.Count; // KFreon: Elapsed time stuff int start = Environment.TickCount; // KFreon: Start threading of save function (max 10 threads) //ParallelOptions po = new ParallelOptions(); //po.MaxDegreeOfParallelism = 2; if (modCount > 1) //Parallel.For(1, modCount, po, (item, loopstate) => for (int item = 1; item < modCount; item++) { Debug.WriteLine(pccs[item] + " " + IDs[item]); WriteDebug(pccs[item] + " " + IDs[item]); if (!SaveFile(pccs, IDs, tex2D, item)) break; /*loopstate.Stop(); });*/ } Debug.WriteLine(""); WriteDebug(""); // KFreon: More timer stuff TimeSpan ts = TimeSpan.FromMilliseconds(Environment.TickCount - start); Console.WriteLine(ts.Duration().ToString()); GC.Collect(); DebugOutput.Print("All PCC updates finished. "); }