/// <summary> /// Checks if two SubPicture object can be merged because the time gap between them is rather small /// and the embedded objects seem to be identical /// </summary> /// <param name="a">first SubPicture object (earlier)</param> /// <param name="b">2nd SubPicture object (later)</param> /// <returns>return true if the SubPictures can be merged</returns> private static bool IsPictureMergable(BluRaySupPicture a, BluRaySupPicture b) { bool eq = false; if (a != null && b != null) { if (a.EndTime == 0 || b.StartTime - a.EndTime < Core.GetMergePtSdiff()) { ImageObject ao = a.ObjectIdImage; ImageObject bo = b.ObjectIdImage; if (ao != null && bo != null) { if (ao.BufferSize == bo.BufferSize && ao.Width == bo.Width && ao.Height == bo.Height) { eq = true; } } } } return(eq); }
/// <summary> /// parse an ODS packet which contain the image data /// </summary> /// <param name="buffer">raw byte date, starting right after segment</param> /// <param name="segment">object containing info about the current segment</param> /// <param name="pic">SubPicture object containing info about the current caption</param> /// <param name="msg">reference to message string</param> /// <returns>true if this is a valid new object (neither invalid nor a fragment)</returns> private static bool ParseOds(byte[] buffer, SupSegment segment, BluRaySupPicture pic, string[] msg) { ImageObjectFragment info; int objId = BigEndianInt16(buffer, 0); // 16bit object_id int objVer = buffer[2]; // 16bit object_id nikse - index 2 or 1??? int objSeq = buffer[3]; // 8bit first_in_sequence (0x80), // last_in_sequence (0x40), 6bits reserved bool first = (objSeq & 0x80) == 0x80; bool last = (objSeq & 0x40) == 0x40; if (pic.ImageObjects == null) { pic.ImageObjects = new List <ImageObject>(); } ImageObject imgObj; if (objId >= pic.ImageObjects.Count) { imgObj = new ImageObject(); pic.ImageObjects.Add(imgObj); } else { imgObj = pic.GetImageObject(objId); } if (imgObj.Fragments == null || first) { // 8bit object_version_number // skipped: // 24bit object_data_length - full RLE buffer length (including 4 bytes size info) int width = BigEndianInt16(buffer, 7); // object_width int height = BigEndianInt16(buffer, 9); // object_height if (width <= pic.Width && height <= pic.Height) { imgObj.Fragments = new List <ImageObjectFragment>(); info = new ImageObjectFragment(); info.ImagePacketSize = segment.Size - 11; // Image packet size (image bytes) info.ImageBuffer = new byte[info.ImagePacketSize]; Buffer.BlockCopy(buffer, 11, info.ImageBuffer, 0, info.ImagePacketSize); imgObj.Fragments.Add(info); imgObj.BufferSize = info.ImagePacketSize; imgObj.Height = height; imgObj.Width = width; msg[0] = "ID: " + objId + ", update: " + objVer + ", seq: " + (first ? "first" : "") + ((first && last) ? "/" : "") + (last ? "" + "last" : ""); return(true); } System.Diagnostics.Debug.Print("Invalid image size - ignored"); return(false); } // object_data_fragment // skipped: // 16bit object_id // 8bit object_version_number // 8bit first_in_sequence (0x80), last_in_sequence (0x40), 6bits reserved info = new ImageObjectFragment(); info.ImagePacketSize = segment.Size - 4; info.ImageBuffer = new byte[info.ImagePacketSize]; Buffer.BlockCopy(buffer, 4, info.ImageBuffer, 0, info.ImagePacketSize); imgObj.Fragments.Add(info); imgObj.BufferSize += info.ImagePacketSize; // total size (may contain several packets) msg[0] = "ID: " + objId + ", update: " + objVer + ", seq: " + (first ? "first" : "") + ((first && last) ? "/" : "") + (last ? "" + "last" : ""); return(false); }