private void RenameAndHandleNewImageInfo(ReceivedImageInfo info) { // Format current (Unix) UTC time so we can use it when renaming file. DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); dateTime = dateTime.AddSeconds(info.triggerInfo.utcTime); string formattedTime = dateTime.ToString("yyyyMMdd_hhmmss"); string originalImageFilename = Path.GetFileName(info.originalFilePath); string newFileName = String.Format("{0}_{1}_{2}_{3}.{4}", InstrumentID, formattedTime, info.imageType, info.imageNumber, info.imageExtension); string newFilePath = Path.Combine(CurrentDataFileDirectory, newFileName); // Rename image. If there's already an image with the same name then delete it first. if (File.Exists(newFilePath)) { File.Delete(newFilePath); } File.Move(info.originalFilePath, newFilePath); HandleData(info.triggerInfo.utcTime, info.triggerInfo.sysTime, new List <object>() { newFileName, info.triggerInfo.sysTime, info.camImageNumber }); }
void CameraHandler_NewImageDownloaded(string originalFilePath) { string imageType; // e.g. IMG or CAM1 int camImageNumber; // e.g. 1 or 1852 string imageExtension; // e.g. JPG or CR2 bool parseSuccessful = ParseImageFilePath(originalFilePath, out imageType, out camImageNumber, out imageExtension); if (!parseSuccessful) { SendText(String.Format("Could not parse image \"{0}\"", Path.GetFileName(originalFilePath))); return; } lastReceivedSysTime = SysTime; // Detect if camera numbering rolled over from 9999 to 1. // Can't just check if new image number is less than last since don't always receive in order. // For example could go 9998 -> 1 -> 9999 -> 2 -> 3... and that would only be one rollover. if (firstImageReceived) { if (lastCamImageNumber > 9000 && camImageNumber < 1000) { numberOfTimesNumberingRolledOver++; } else if (lastCamImageNumber < 1000 && camImageNumber > 9000) { // Rare case of rolled over, but then got out of order, so need to undo rollover, which should then // shortly be re-done in either the next image or the one after that. numberOfTimesNumberingRolledOver--; } } // Save this so we know for next time. lastCamImageNumber = camImageNumber; // Convert image number into OUR numbering scheme (i.e. doesn't wrap at 9999) int imageNumber = camImageNumber + (numberOfTimesNumberingRolledOver * 9999); // Find matching number in trigger info so we know what time the picture was taken at. // Iterate backwards through list so we can safetly delete elements. // If we haven't received first image yet then we want to use the first triggerInfo and clear the entire list. TriggerImageInfo matchingTrigger = null; for (int i = triggerImageInfo.Count - 1; i >= 0; i--) { TriggerImageInfo trigger = triggerImageInfo[i]; if (!firstImageReceived || (trigger.expectedImageNumber == imageNumber)) { matchingTrigger = trigger; triggerImageInfo.RemoveAt(i); } } if (matchingTrigger == null) { SendText(String.Format("Could find matching trigger info for image number {0}", imageNumber)); DontKnowWhatNumberToExpect(); return; } // We have valid information for our newly downloaded image. ReceivedImageInfo receivedInfo = new ReceivedImageInfo(originalFilePath, matchingTrigger, imageType, imageNumber, camImageNumber, imageExtension); // Set a flag to determine we want to handle data (rename and send) right now or if we need to // wait because it's out of order. bool handleNewImageRightNow = true; if (!firstImageReceived) { firstImageReceived = true; nextExpectedReceivedNumber = imageNumber + 1; nextExpectedTriggerNumber = imageNumber + 1; } else // we know what the next number should be, so verify it. { if (matchingTrigger.expectedImageNumber < nextExpectedReceivedNumber) { SendText(String.Format("Received image number {0} is lower than expected {1}. This should never happen.", imageNumber, nextExpectedReceivedNumber)); DontKnowWhatNumberToExpect(); // return; handle it anyways... it will just be out of order in the log, but still correct. } else if (matchingTrigger.expectedImageNumber > nextExpectedReceivedNumber) { // Received image out of order. This is normal. Just buffer it to write it out later. handleNewImageRightNow = false; bufferedImageInfo.Add(receivedInfo); } else { // We received the one we were expecting... so now we should start expecting the next one.s nextExpectedReceivedNumber++; } } if (handleNewImageRightNow) { RenameAndHandleNewImageInfo(receivedInfo); // Handle any other buffered elements that immediately follow this one. bool handledBufferImage = true; while (handledBufferImage) { handledBufferImage = false; // Assume we won't find any matching buffer elements. for (int i = bufferedImageInfo.Count - 1; i >= 0; i--) { ReceivedImageInfo info = bufferedImageInfo[i]; if (info.triggerInfo.expectedImageNumber == nextExpectedReceivedNumber) { //SendText("Flushing " + info.imageNumber); RenameAndHandleNewImageInfo(info); nextExpectedReceivedNumber++; bufferedImageInfo.RemoveAt(i); handledBufferImage = true; // so keep looking for next one. break; // only try to match one each time through loop. } } } } else { // Make sure we haven't buffered up too many images. This is a sign that the image we're expecting is // never going to come. In that case just handle everything we have and start expecting the next one. if (bufferedImageInfo.Count > 5) { List <ReceivedImageInfo> sortedBufferedImageInfo = bufferedImageInfo.OrderBy(o => o.triggerInfo.expectedImageNumber).ToList(); foreach (ReceivedImageInfo info in sortedBufferedImageInfo) { //SendText("Fail Flushing " + info.imageNumber); RenameAndHandleNewImageInfo(info); } DontKnowWhatNumberToExpect(); bufferedImageInfo.Clear(); // since we just handled them all. } } }