/** * {@collect.stats} Filters an IndexColorModel object by running each entry in its color tables * through the filterRGB function that RGBImageFilter subclasses must provide. Uses coordinates of * -1 to indicate that a color table entry is being filtered rather than an actual pixel value. * * @param icm the IndexColorModel object to be filtered * @exception NullPointerException if <code>icm</code> is null * @return a new IndexColorModel representing the filtered colors */ public IndexColorModel filterIndexColorModel(IndexColorModel icm) { int mapsize = icm.getMapSize(); byte r[] = new byte[mapsize]; byte g[] = new byte[mapsize]; byte b[] = new byte[mapsize]; byte a[] = new byte[mapsize]; icm.getReds(r); icm.getGreens(g); icm.getBlues(b); icm.getAlphas(a); int trans = icm.getTransparentPixel(); boolean needalpha = false; for (int i = 0; i < mapsize; i++) { int rgb = filterRGB(-1, -1, icm.getRGB(i)); a[i] = (byte) (rgb >> 24); if (a[i] != ((byte) 0xff) && i != trans) { needalpha = true; } r[i] = (byte) (rgb >> 16); g[i] = (byte) (rgb >> 8); b[i] = (byte) (rgb >> 0); } if (needalpha) { return new IndexColorModel(icm.getPixelSize(), mapsize, r, g, b, a); } else { return new IndexColorModel(icm.getPixelSize(), mapsize, r, g, b, trans); } }
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(); } int rassize = width * height; byte[] rasfill = new byte[rassize]; if (tpix != 0) { for (int i = 0; i < rassize; i++) { rasfill[i] = tpix; } } // setPixels(x, y, width, height, model, rasfill, 0, 0); setPixels(x, y, width, height, model, rasfill, 0, width); break; case DISPOSAL_SAVE: decoder.saved_model = model; break; } } return true; }
/** Read Image data */ private boolean readImage(boolean first, int disposal_method, int delay) throws IOException { if (curframe != null && !curframe.dispose()) { abort(); return false; } long tm = 0; if (verbose) { tm = System.currentTimeMillis(); } // Allocate the buffer byte block[] = new byte[256 + 3]; // Read the image descriptor if (readBytes(block, 0, 10) != 0) { throw new IOException(); } int x = ExtractWord(block, 0); int y = ExtractWord(block, 2); int width = ExtractWord(block, 4); int height = ExtractWord(block, 6); boolean interlace = (block[8] & INTERLACEMASK) != 0; 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(); } model = new IndexColorModel(8, num_local_colors, local_colormap, 0, false, trans_pixel); } else if (model == null || trans_pixel != model.getTransparentPixel()) { 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]; } 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..."); } boolean ret = parseImage(x, y, width, height, interlace, ExtractByte(block, 9), block, rasline, model); if (!ret) { abort(); } if (verbose) { System.out.println("done in " + (System.currentTimeMillis() - tm) + "ms"); } return ret; }