Ejemplo n.º 1
0
 public void AddColorTable(ColorTable colortable)
 {
     m_ctables.Add(colortable);
 }
Ejemplo n.º 2
0
        protected override void LoadImage()
        {
            m_bitsPerPixel = 8;
            m_isTransparent = false;
            m_colorSpace = new ColorSpace();
            ColorSpace.AddDevice(ColorDevice.Indexed);
            ColorSpace.AddDevice(ColorDevice.DeviceRGB);

            //add the LZW filter
            m_filter = new LZWFilter(); //migth need some parameters! '/EarlyChange' for instance

            var ImageHolder = new FileStream(m_href, FileMode.Open, FileAccess.Read, FileShare.Read, 8192);
            var len = (int) ImageHolder.Length;
            var buf = new byte[len + 1]; //the +1 is a dirty hack , don't like it
            ImageHolder.Read(buf, 0, len);

            var state = gif_states.gif_init;
            var colorTableSize = 0;
            var p = 0;

            while (true)
            {
                switch (state)
                {
                    case gif_states.gif_init:

                        if (buf[0] != 0x47 || buf[1] != 0x49 || buf[2] != 0x46)
                            throw new ImageFormatException("Invalid GIF format : No a GIF file.");

                        /// p = 6 ; // version ~ uninsteresting

                        m_width = toShortInverted(buf[6], buf[7]);
                        m_height = toShortInverted(buf[8], buf[9]);

                        byte packed_field = buf[10];

                        colorTableSize = 2 << (packed_field & 0x07);

                        //byte 11: Background Color Index
                        //byte 12: Pixel Aspect Ratio

                        p = 13;

                        state = (packed_field & 0x80) == 0 ? gif_states.gif_image_start : gif_states.gif_global_colormap;
                        break;

                    case gif_states.gif_global_colormap:

                        var ct = new ColorTable(colorTableSize);

                        for (int i = 0; i < colorTableSize; i++)
                        {
                            ct.AddItem(buf[p++]); //red
                            ct.AddItem(buf[p++]); //green
                            ct.AddItem(buf[p++]); //blue
                        }

                        ColorSpace.AddColorTable(ct);
                        state = gif_states.gif_image_start;
                        break;

                    case gif_states.gif_image_start:
                        int first_code = buf[p++];
                        if (first_code == 0x3b) //terminator ';'
                        {
                            state = gif_states.gif_done;
                            break;
                        }
                        if (first_code == 0x21) //extension '!'
                        {
                            state = gif_states.gif_extension;
                            break;
                        }
                        if (first_code != 0x2c) //invalid format , should be ','
                            throw new ImageFormatException("Invalid GIF format : image separator code (0x2C) not found.");

                        state = gif_states.gif_image_header;

                        break;

                    case gif_states.gif_extension:
                        int ext_code = buf[p++];
                        int jump_len = buf[p++];
                        state = gif_states.gif_skip_block;

                        switch (ext_code)
                        {
                            case 0xf9:
                                state = gif_states.gif_control_extension;
                                break;
                            case 0x01:
                                //just ignoring plain text extension
                                break;
                            case 0xff:
                                state = gif_states.gif_application_extension;
                                break;
                            case 0xfe:
                                state = gif_states.gif_consume_comment;
                                break;
                        }
                        if (jump_len > 0)
                        {
                            p = p + jump_len;
                        }
                        else
                            state = gif_states.gif_image_start;

                        break;

                    case gif_states.gif_consume_block:
                        if (buf[p] == 0)
                        {
                            state = gif_states.gif_image_start;
                            p++;
                        }
                        else
                        {
                            p = p + buf[p];
                            state = gif_states.gif_skip_block;
                        }
                        break;
                    case gif_states.gif_skip_block:

                        state = gif_states.gif_image_start;
                        break;
                    case gif_states.gif_control_extension:
                        //    here i should check for transparency
                        state = gif_states.gif_consume_block;
                        break;
                    case gif_states.gif_comment_extension:
                        if (buf[p] > 0)
                        {
                            p = p + buf[p];
                            state = gif_states.gif_consume_comment;
                        }
                        else
                            state = gif_states.gif_image_start;
                        break;
                    case gif_states.gif_consume_comment:
                        state = gif_states.gif_comment_extension;
                        break;
                    case gif_states.gif_application_extension:
                        state = gif_states.gif_consume_block;
                        break;
                    case gif_states.gif_image_header:
                        p = p + 8;

                        packed_field = buf[p++];

                        int localColorTableFlag = (packed_field & 0x80); //bit 1
                        int interlaceFlag = (packed_field & 0x40); //bit 2
                        int sizeLocalColorTable = 2 << (packed_field & 0x07); //last 3 bits

                        if (localColorTableFlag > 0)
                        {
                            throw new ImageFormatException("Invalid GIF format : Local Color Tables not supported.");
                        }
                        if (interlaceFlag > 0)
                        {
                            throw new ImageFormatException("Invalid GIF format : Interlaced GIF's not supported.");
                        }

                        //i'm assuming there's no local color table
                        state = gif_states.gif_lzw_start;
                        break;
                    case gif_states.gif_lzw_start:
                        p++;
                        state = gif_states.gif_sub_block;
                        break;
                    case gif_states.gif_sub_block:
                        if (buf[p] != 0)
                        {
                            //read ahead
                            proc_sblock(buf, buf[p], p + 1);
                            ms.Flush();
                            m_bitmaps = ms.ToArray();
                            return;
                        }

                        break;
                    case gif_states.gif_done:
                        return;
                }
            }
        }