Ejemplo n.º 1
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();
            }
        private static Bitmap CropBitmapAndUnlok(FastBitmap bmp, Color backgroundColor)
        {
            int y = 0;
            int x;
            Color c = backgroundColor;
            int backgroundArgb = backgroundColor.ToArgb();

            // Crop top
            while (y < bmp.Height && IsBackgroundColor(c, backgroundArgb))
            {
                c = bmp.GetPixel(0, y);
                if (IsBackgroundColor(c, backgroundArgb))
                {
                    for (x = 1; x < bmp.Width; x++)
                    {
                        c = bmp.GetPixelNext();
                        if (c.A != 0 && c.ToArgb() != backgroundArgb)
                            break;
                    }
                }
                if (IsBackgroundColor(c, backgroundArgb))
                    y++;
            }
            int minY = y;
            if (minY > 3)
                minY -= 3;
            else
                minY = 0;

            // Crop left
            x = 0;
            c = backgroundColor;
            while (x < bmp.Width && IsBackgroundColor(c, backgroundArgb))
            {
                for (y = minY; y < bmp.Height; y++)
                {
                    c = bmp.GetPixel(x, y);
                    if (!IsBackgroundColor(c, backgroundArgb))
                        break;
                }
                if (IsBackgroundColor(c, backgroundArgb))
                    x++;
            }
            int minX = x;
            if (minX > 3)
                minX -= 3;
            else
                minX -= 0;

            // Crop bottom
            y = bmp.Height - 1;
            c = backgroundColor;
            while (y > minY && IsBackgroundColor(c, backgroundArgb))
            {
                c = bmp.GetPixel(0, y);
                if (IsBackgroundColor(c, backgroundArgb))
                {
                    for (x = 1; x < bmp.Width; x++)
                    {
                        c = bmp.GetPixelNext();
                        if (!IsBackgroundColor(c, backgroundArgb))
                            break;
                    }
                }
                if (IsBackgroundColor(c, backgroundArgb))
                    y--;
            }
            int maxY = y + 7;
            if (maxY >= bmp.Height)
                maxY = bmp.Height - 1;

            // Crop right
            x = bmp.Width - 1;
            c = backgroundColor;
            while (x > minX && IsBackgroundColor(c, backgroundArgb))
            {
                for (y = minY; y < bmp.Height; y++)
                {
                    c = bmp.GetPixel(x, y);
                    if (!IsBackgroundColor(c, backgroundArgb))
                        break;
                }
                if (IsBackgroundColor(c, backgroundArgb))
                    x--;
            }
            int maxX = x + 7;
            if (maxX >= bmp.Width)
                maxX = bmp.Width - 1;

            bmp.UnlockImage();
            Bitmap bmpImage = bmp.GetBitmap();
            if (bmpImage.Width > 1 && bmpImage.Height > 1 && maxX - minX > 0 && maxY - minY > 0)
            {
                Bitmap bmpCrop = bmpImage.Clone(new Rectangle(minX, minY, maxX - minX, maxY - minY), bmpImage.PixelFormat);
                return bmpCrop;
            }
            return (Bitmap)bmpImage.Clone();
        }