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 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; }