753 lines · 26.5 KB · Java
RawDownload
        IndexColorModel model = global_model;         if ((block[8] & COLORMAPMASK) != 0) {            // We read one extra byte above so now when we must            // transfer that byte as the first colormap byte            // and manually read the code size when we are done            int num_local_colors = 1 << ((block[8] & 0x7) + 1);             // Read local colors            byte[] local_colormap = new byte[num_local_colors * 3];            local_colormap[0] = block[9];            if (readBytes(local_colormap, 1, num_local_colors * 3 - 1) != 0) {                throw new IOException();            }             // Now read the "real" code size byte which follows            // the local color table            if (readBytes(block, 9, 1) != 0) {                throw new IOException();            }            if (trans_pixel >= num_local_colors) {                // Fix for 4233748: extend colormap to contain transparent pixel                num_local_colors = trans_pixel + 1;                local_colormap = grow_colormap(local_colormap, num_local_colors);            }            model = new IndexColorModel(8, num_local_colors, local_colormap,                                        0, false, trans_pixel);        } else if (model == null                   || trans_pixel != model.getTransparentPixel()) {            if (trans_pixel >= num_global_colors) {                // Fix for 4233748: extend colormap to contain transparent pixel                num_global_colors = trans_pixel + 1;                global_colormap = grow_colormap(global_colormap, num_global_colors);            }            model = new IndexColorModel(8, num_global_colors, global_colormap,                                        0, false, trans_pixel);            global_model = model;        }         // Notify the consumers        if (first) {            if (global_width == 0) global_width = width;            if (global_height == 0) global_height = height;             setDimensions(global_width, global_height);            setProperties(props);            setColorModel(model);            headerComplete();        }         if (disposal_method == GifFrame.DISPOSAL_SAVE && saved_image == null) {            saved_image = new byte[global_width * global_height];            /*             * If height of current image is smaller than the global height,             * fill the gap with transparent pixels.             */            if ((height < global_height) && (model != null)) {                byte tpix = (byte)model.getTransparentPixel();                if (tpix >= 0) {                    byte trans_rasline[] = new byte[global_width];                    for (int i=0; i<global_width;i++) {                        trans_rasline[i] = tpix;                    }                     setPixels(0, 0, global_width, y,                              model, trans_rasline, 0, 0);                    setPixels(0, y+height, global_width,                              global_height-height-y, model, trans_rasline,                              0, 0);                }            }        }         int hints = (interlace ? interlaceflags : normalflags);        setHints(hints);         curframe = new GifFrame(this, disposal_method, delay,                                (curframe == null), model,                                x, y, width, height);         // allocate the raster data        byte rasline[] = new byte[width];         if (verbose) {            System.out.print("Reading a " + width + " by " + height + " " +                      (interlace ? "" : "non-") + "interlaced image...");        }        int initCodeSize = ExtractByte(block, 9);        if (initCodeSize >= 12) {            if (verbose) {                System.out.println("Invalid initial code size: " +                                   initCodeSize);            }            return false;        }        boolean ret = parseImage(x, y, width, height,                                 interlace, initCodeSize,                                 block, rasline, model);         if (!ret) {            abort();        }         if (verbose) {            System.out.println("done in "                               + (System.currentTimeMillis() - tm)                               + "ms");        }         return ret;    }     public static byte[] grow_colormap(byte[] colormap, int newlen) {        byte[] newcm = new byte[newlen * 3];        System.arraycopy(colormap, 0, newcm, 0, colormap.length);        return newcm;    }} class GifFrame {    private static final boolean verbose = false;    private static IndexColorModel trans_model;     static final int DISPOSAL_NONE      = 0x00;    static final int DISPOSAL_SAVE      = 0x01;    static final int DISPOSAL_BGCOLOR   = 0x02;    static final int DISPOSAL_PREVIOUS  = 0x03;     GifImageDecoder decoder;     int disposal_method;    int delay;     IndexColorModel model;     int x;    int y;    int width;    int height;     boolean initialframe;     public GifFrame(GifImageDecoder id, int dm, int dl, boolean init,                    IndexColorModel cm, int x, int y, int w, int h) {        this.decoder = id;        this.disposal_method = dm;        this.delay = dl;        this.model = cm;        this.initialframe = init;        this.x = x;        this.y = y;        this.width = w;        this.height = h;    }     private void setPixels(int x, int y, int w, int h,                           ColorModel cm, byte[] pix, int off, int scan) {        decoder.setPixels(x, y, w, h, cm, pix, off, scan);    }     public boolean dispose() {        if (decoder.imageComplete(ImageConsumer.SINGLEFRAMEDONE, false) == 0) {            return false;        } else {            if (delay > 0) {                try {                    if (verbose) {                        System.out.println("sleeping: "+delay);                    }                    Thread.sleep(delay);                } catch (InterruptedException e) {                    return false;                }            } else {                Thread.yield();            }             if (verbose && disposal_method != 0) {                System.out.println("disposal method: "+disposal_method);            }             int global_width = decoder.global_width;            int global_height = decoder.global_height;             if (x < 0) {                width += x;                x = 0;            }            if (x + width > global_width) {                width = global_width - x;            }            if (width <= 0) {                disposal_method = DISPOSAL_NONE;            } else {                if (y < 0) {                    height += y;                    y = 0;                }                if (y + height > global_height) {                    height = global_height - y;                }                if (height <= 0) {                    disposal_method = DISPOSAL_NONE;                }            }             switch (disposal_method) {            case DISPOSAL_PREVIOUS:                byte[] saved_image = decoder.saved_image;                IndexColorModel saved_model = decoder.saved_model;                if (saved_image != null) {                    setPixels(x, y, width, height,                              saved_model, saved_image,                              y * global_width + x, global_width);                }                break;            case DISPOSAL_BGCOLOR:                byte tpix;                if (model.getTransparentPixel() < 0) {                    model = trans_model;                    if (model == null) {                        model = new IndexColorModel(8, 1,                                                    new byte[4], 0, true);                        trans_model = model;                    }                    tpix = 0;                } else {                    tpix = (byte) model.getTransparentPixel();                }                byte[] rasline = new byte[width];                if (tpix != 0) {                    for (int i = 0; i < width; i++) {                        rasline[i] = tpix;                    }                }                 // clear saved_image using transparent pixels                // this will be used as the background in the next display                if( decoder.saved_image != null ) {                    for( int i = 0; i < global_width * global_height; i ++ )                        decoder.saved_image[i] = tpix;                }                 setPixels(x, y, width, height, model, rasline, 0, 0);                break;            case DISPOSAL_SAVE:                decoder.saved_model = model;                break;            }        }        return true;    }}

Lines 501–753 of 753. Previous lines