Esempio n. 1
0
        /// <summary>
        /// Parse an PCS packet which contains width/height info
        /// </summary>
        /// <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>
        /// <param name="buffer">Raw data buffer, starting right after segment</param>
        private static PcsObject ParsePcs(byte[] buffer, int offset)
        {
            var pcs = new PcsObject();

            // composition_object:
            pcs.ObjectId = BigEndianInt16(buffer, 11 + offset); // 16bit object_id_ref
            pcs.WindowId = buffer[13 + offset];
            // skipped:  8bit  window_id_ref
            // object_cropped_flag: 0x80, forced_on_flag = 0x040, 6bit reserved
            int forcedCropped = buffer[14 + offset];

            pcs.IsForced = ((forcedCropped & 0x40) == 0x40);
            pcs.Origin   = new Point(BigEndianInt16(buffer, 15 + offset), BigEndianInt16(buffer, 17 + offset));
            return(pcs);
        }
Esempio n. 2
0
        private static PcsData ParsePicture(byte[] buffer, SupSegment segment)
        {
            var sb  = new StringBuilder();
            var pcs = new PcsData();

            pcs.Size = new Size(BigEndianInt16(buffer, 0), BigEndianInt16(buffer, 2));
            pcs.FramesPerSecondType = buffer[4];                // hi nibble: frame_rate, lo nibble: reserved
            pcs.CompNum             = BigEndianInt16(buffer, 5);
            pcs.CompositionState    = GetCompositionState(buffer[7]);
            pcs.StartTime           = segment.PtsTimestamp;
            // 8bit  palette_update_flag (0x80), 7bit reserved
            pcs.PaletteUpdate = (buffer[8] == 0x80);
            pcs.PaletteId     = buffer[9];           // 8bit  palette_id_ref
            int compositionObjectCount = buffer[10]; // 8bit  number_of_composition_objects (0..2)

            sb.AppendFormat("CompNum: {0}, Pts: {1}, State: {2}, PalUpdate: {3}, PalId {4}", pcs.CompNum, ToolBox.PtsToTimeString(pcs.StartTime), pcs.CompositionState, pcs.PaletteUpdate, pcs.PaletteId);

            if (pcs.CompositionState == CompositionState.Invalid)
            {
                sb.Append("Illegal composition state Invalid");
            }
            else
            {
                int offset = 0;
                pcs.PcsObjects = new List <PcsObject>();
                for (int compObjIndex = 0; compObjIndex < compositionObjectCount; compObjIndex++)
                {
                    PcsObject pcsObj = ParsePcs(buffer, offset);
                    pcs.PcsObjects.Add(pcsObj);
                    sb.AppendLine();
                    sb.AppendFormat("ObjId: {0}, WinId: {1}, Forced: {2}, X: {3}, Y: {4}",
                                    pcsObj.ObjectId, pcsObj.WindowId, pcsObj.IsForced, pcsObj.Origin.X, pcsObj.Origin.Y);
                    offset += 8;
                }
            }
            pcs.Message = sb.ToString();
            return(pcs);
        }
Esempio n. 3
0
            /// <summary>
            /// Decode caption from the input stream
            /// </summary>
            /// <returns>bitmap of the decoded caption</returns>
            public static Bitmap DecodeImage(PcsObject pcs, IList<OdsData> data, List<PaletteInfo> palettes)
            {
                if (pcs == null || data == null || data.Count == 0)
                    return new Bitmap(1, 1);

                int w = data[0].Size.Width;
                int h = data[0].Size.Height;

                var bm = new FastBitmap(new Bitmap(w, h));
                bm.LockImage();
                BluRaySupPalette pal = DecodePalette(palettes);

                int index = 0;
                int ofs = 0;
                int xpos = 0;

                byte[] buf = data[0].Fragment.ImageBuffer;
                index = 0;
                do
                {
                    int b = buf[index++] & 0xff;
                    if (b == 0 && index < buf.Length)
                    {
                        b = buf[index++] & 0xff;
                        if (b == 0)
                        {
                            // next line
                            ofs = (ofs / w) * w;
                            if (xpos < w)
                                ofs += w;
                            xpos = 0;
                        }
                        else
                        {
                            int size;
                            if ((b & 0xC0) == 0x40)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 4x xx -> xxx zeroes
                                    size = ((b - 0x40) << 8) + (buf[index++] & 0xff);
                                    Color c = Color.FromArgb(pal.GetArgb(0));
                                    for (int i = 0; i < size; i++)
                                        PutPixel(bm, ofs++, c);
                                    xpos += size;
                                }
                            }
                            else if ((b & 0xC0) == 0x80)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 8x yy -> x times value y
                                    size = (b - 0x80);
                                    b = buf[index++] & 0xff;
                                    Color c = Color.FromArgb(pal.GetArgb(b));
                                    for (int i = 0; i < size; i++)
                                        PutPixel(bm, ofs++, c);
                                    xpos += size;
                                }
                            }
                            else if ((b & 0xC0) != 0)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 cx yy zz -> xyy times value z
                                    size = ((b - 0xC0) << 8) + (buf[index++] & 0xff);
                                    b = buf[index++] & 0xff;
                                    Color c = Color.FromArgb(pal.GetArgb(b));
                                    for (int i = 0; i < size; i++)
                                        PutPixel(bm, ofs++, c);
                                    xpos += size;
                                }
                            }
                            else
                            {
                                // 00 xx -> xx times 0
                                Color c = Color.FromArgb(pal.GetArgb(0));
                                for (int i = 0; i < b; i++)
                                    PutPixel(bm, ofs++, c);
                                xpos += b;
                            }
                        }
                    }
                    else
                    {
                        PutPixel(bm, ofs++, b, pal);
                        xpos++;
                    }
                } while (index < buf.Length);

                bm.UnlockImage();
                return bm.GetBitmap();
            }
Esempio n. 4
0
 /// <summary>
 /// Parse an PCS packet which contains width/height info
 /// </summary>
 /// <param name="buffer">Raw data buffer, starting right after segment</param>
 private static PcsObject ParsePcs(byte[] buffer, int offset)
 {
     var pcs = new PcsObject();
     // composition_object:
     pcs.ObjectId = BigEndianInt16(buffer, 11 + offset); // 16bit object_id_ref
     pcs.WindowId = buffer[13 + offset];
     // skipped:  8bit  window_id_ref
     // object_cropped_flag: 0x80, forced_on_flag = 0x040, 6bit reserved
     int forcedCropped = buffer[14 + offset];
     pcs.IsForced = ((forcedCropped & 0x40) == 0x40);
     pcs.Origin = new Point(BigEndianInt16(buffer, 15 + offset), BigEndianInt16(buffer, 17 + offset));
     return pcs;
 }
Esempio n. 5
0
            /// <summary>
            /// Decode caption from the input stream
            /// </summary>
            /// <returns>bitmap of the decoded caption</returns>
            public static Bitmap DecodeImage(PcsObject pcs, IList <OdsData> data, List <PaletteInfo> palettes)
            {
                if (pcs == null || data == null || data.Count == 0)
                {
                    return(new Bitmap(1, 1));
                }

                int w = data[0].Size.Width;
                int h = data[0].Size.Height;

                if (w <= 0 || h <= 0 || data[0].Fragment.ImageBuffer.Length == 0)
                {
                    return(new Bitmap(1, 1));
                }

                var bm = new FastBitmap(new Bitmap(w, h));

                bm.LockImage();
                var pal = DecodePalette(palettes);

                int ofs   = 0;
                int xpos  = 0;
                var index = 0;

                byte[] buf = data[0].Fragment.ImageBuffer;
                do
                {
                    int b = buf[index++] & 0xff;
                    if (b == 0 && index < buf.Length)
                    {
                        b = buf[index++] & 0xff;
                        if (b == 0)
                        {
                            // next line
                            ofs = ofs / w * w;
                            if (xpos < w)
                            {
                                ofs += w;
                            }

                            xpos = 0;
                        }
                        else
                        {
                            int size;
                            if ((b & 0xC0) == 0x40)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 4x xx -> xxx zeroes
                                    size = ((b - 0x40) << 8) + (buf[index++] & 0xff);
                                    var c = Color.FromArgb(pal.GetArgb(0));
                                    for (int i = 0; i < size; i++)
                                    {
                                        PutPixel(bm, ofs++, c);
                                    }

                                    xpos += size;
                                }
                            }
                            else if ((b & 0xC0) == 0x80)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 8x yy -> x times value y
                                    size = (b - 0x80);
                                    b    = buf[index++] & 0xff;
                                    var c = Color.FromArgb(pal.GetArgb(b));
                                    for (int i = 0; i < size; i++)
                                    {
                                        PutPixel(bm, ofs++, c);
                                    }

                                    xpos += size;
                                }
                            }
                            else if ((b & 0xC0) != 0)
                            {
                                if (index < buf.Length)
                                {
                                    // 00 cx yy zz -> xyy times value z
                                    size = ((b - 0xC0) << 8) + (buf[index++] & 0xff);
                                    b    = buf[index++] & 0xff;
                                    var c = Color.FromArgb(pal.GetArgb(b));
                                    for (int i = 0; i < size; i++)
                                    {
                                        PutPixel(bm, ofs++, c);
                                    }

                                    xpos += size;
                                }
                            }
                            else
                            {
                                // 00 xx -> xx times 0
                                var c = Color.FromArgb(pal.GetArgb(0));
                                for (int i = 0; i < b; i++)
                                {
                                    PutPixel(bm, ofs++, c);
                                }

                                xpos += b;
                            }
                        }
                    }
                    else
                    {
                        PutPixel(bm, ofs++, b, pal);
                        xpos++;
                    }
                } while (index < buf.Length);

                bm.UnlockImage();
                return(bm.GetBitmap());
            }
Esempio n. 6
0
        /// <summary>
        /// Decode caption from the input stream
        /// </summary>
        /// <returns>bitmap of the decoded caption</returns>
        public static Image <Rgba32> DecodeImage(PcsObject pcs, IList <OdsData> data, List <PaletteInfo> palettes)
        {
            if (pcs == null || data == null || data.Count == 0)
            {
                return(new Image <Rgba32>(1, 1));
            }

            int w = data[0].Size.Width;
            int h = data[0].Size.Height;

            var pal = BluRaySupParser.SupDecoder.DecodePalette(palettes);
            var bm  = new Image <Rgba32>(w, h);

            bm.TryGetSinglePixelSpan(out var pixelSpan);

            int ofs   = 0;
            int xpos  = 0;
            var index = 0;

            byte[] buf = data[0].Fragment.ImageBuffer;
            do
            {
                int b = buf[index++] & 0xff;
                if (b == 0 && index < buf.Length)
                {
                    b = buf[index++] & 0xff;
                    if (b == 0)
                    {
                        // next line
                        ofs = (ofs / w) * w;
                        if (xpos < w)
                        {
                            ofs += w;
                        }
                        xpos = 0;
                    }
                    else
                    {
                        int size;
                        if ((b & 0xC0) == 0x40)
                        {
                            if (index < buf.Length)
                            {
                                // 00 4x xx -> xxx zeroes
                                size = ((b - 0x40) << 8) + (buf[index++] & 0xff);
                                var c = GetColorFromInt(pal.GetArgb(0));
                                for (int i = 0; i < size; i++)
                                {
                                    PutPixel(pixelSpan, ofs++, c);
                                }
                                xpos += size;
                            }
                        }
                        else if ((b & 0xC0) == 0x80)
                        {
                            if (index < buf.Length)
                            {
                                // 00 8x yy -> x times value y
                                size = (b - 0x80);
                                b    = buf[index++] & 0xff;
                                var c = GetColorFromInt(pal.GetArgb(b));
                                for (int i = 0; i < size; i++)
                                {
                                    PutPixel(pixelSpan, ofs++, c);
                                }
                                xpos += size;
                            }
                        }
                        else if ((b & 0xC0) != 0)
                        {
                            if (index < buf.Length)
                            {
                                // 00 cx yy zz -> xyy times value z
                                size = ((b - 0xC0) << 8) + (buf[index++] & 0xff);
                                b    = buf[index++] & 0xff;
                                var c = GetColorFromInt(pal.GetArgb(b));
                                for (int i = 0; i < size; i++)
                                {
                                    PutPixel(pixelSpan, ofs++, c);
                                }
                                xpos += size;
                            }
                        }
                        else
                        {
                            // 00 xx -> xx times 0
                            var c = GetColorFromInt(pal.GetArgb(0));
                            for (int i = 0; i < b; i++)
                            {
                                PutPixel(pixelSpan, ofs++, c);
                            }
                            xpos += b;
                        }
                    }
                }
                else
                {
                    PutPixel(pixelSpan, ofs++, b, pal);
                    xpos++;
                }
            } while (index < buf.Length);

            return(bm);
        }