/// <summary> /// If opening fails, the state is the same as it was before the open. /// </summary> /// <param name="path"></param> public void Open(string path) { ThrowIfDisposed(); // Open new file first to get any errors out of the way, then switch to it NpkReader newReader = null; FileStream newStream = null; try { newReader = new NpkReader(path); newStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (Exception) { if (newStream != null) { newStream.Dispose(); newReader.Dispose(); } throw; } NpkReader oldReader = _reader; FileStream oldStream = _npkStream; _reader = newReader; _npkStream = newStream; _openFilePath = path; if (oldStream != null) { oldStream.Dispose(); } if (oldReader != null) { oldReader.Dispose(); } }
/// <summary> /// /// </summary> /// <param name="imgPath"></param> /// <param name="frameIndex"></param> /// <param name="newFrameMetadata">If this indicates a link frame, <paramref name="newFramePixels"/> is ignored. The IsCompressed flag is honored, compressing the image if it is set. The CompressedLength field is not used.</param> /// <param name="newFramePixels">Readable stream consisting solely of the pixel data, in the format indicated by the metadata.</param> public void EditFrame(NpkPath imgPath, int frameIndex, FrameInfo newFrameMetadata, Stream newFramePixels) { ThrowIfDisposed(); ThrowIfNoFileOpen(); if (!_reader.Frames.ContainsKey(imgPath)) { throw new ArgumentException("{0} is not in the NPK.".F(imgPath)); } if (frameIndex >= _reader.Frames[imgPath].Count) { throw new ArgumentException("{0} does not have a frame {1}.".F(imgPath, frameIndex)); } NpkFileTableEntry entryOfImgEditing = _reader.Files.Where(f => f.Name.Equals(imgPath)).First(); IReadOnlyList <FrameInfo> frameListOfImgEditing = _reader.Frames[imgPath]; FrameInfo frameMetadataOfFrameEditing = frameListOfImgEditing[frameIndex]; // Render the new frame in memory // pixelData is null if it's a link frame // pixelData length may be bigger than the actual pixel data. Use newPixelDataLength instead of newPixelData.Length int newPixelDataLength; byte[] newPixelData = GetPixelData(newFrameMetadata, newFramePixels, out newPixelDataLength); byte[] frameMetadataBytes = GetFrameMetadataBytes(newFrameMetadata, newPixelDataLength); string tempNpkPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".NPK"); using (FileStream tempFileStream = File.OpenWrite(tempNpkPath)) { WriteEditedNPK(tempFileStream, imgPath, entryOfImgEditing, frameIndex, frameListOfImgEditing, frameMetadataOfFrameEditing, newFrameMetadata, newPixelData, newPixelDataLength, frameMetadataBytes); } // temp file now has the new NPK! // close _reader // close _npkStream // delete original file // move temp file // TODO: "refresh" it _reader.Dispose(); _npkStream.Dispose(); // TODO: Error handling File.Delete(_openFilePath); File.Move(tempNpkPath, _openFilePath); // reopen try { _reader = new NpkReader(_openFilePath); } catch (Exception) { _openFilePath = null; _reader = null; _npkStream = null; throw; } try { _npkStream = new FileStream(_openFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (Exception) { _openFilePath = null; _reader.Dispose(); _reader = null; _npkStream = null; throw; } }