public IndexColorModel transformMap(IndexColorModel icm) { if (!icm.hasAlpha()) throw new IllegalArgumentException("Must have alpha channel in order to scale alpha!"); byte[][] table = ColorMapUtils.extractTable(icm); table[3] = linearScale(table[3]); icm = new IndexColorModel(8, icm.getMapSize(), table[0], table[1], table[2], table[3]); return icm; }
private RenderedImage forceComponentColorModel(RenderedImage image) { final IndexColorModel icm = (IndexColorModel) image.getColorModel(); final SampleModel sm = image.getSampleModel(); final int datatype = sm.getDataType(); final boolean alpha = icm.hasAlpha(); // Definition of the lookup table final int numDestinationBands = 4; LookupTableJAI lut = null; final byte data[][] = new byte[numDestinationBands][icm.getMapSize()]; icm.getReds(data[0]); icm.getGreens(data[1]); icm.getBlues(data[2]); icm.getAlphas(data[3]); lut = new LookupTableJAI(data); // Layout creation final ImageLayout layout = new ImageLayout(image); final RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout); int[] bits = new int[numDestinationBands]; // bits per component for (int i = 0; i < numDestinationBands; i++) bits[i] = sm.getSampleSize(i); final ComponentColorModel destinationColorModel = new ComponentColorModel( ColorSpace.getInstance(ColorSpace.CS_sRGB), bits, alpha, image.getColorModel().isAlphaPremultiplied(), alpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE, datatype); final SampleModel destinationSampleModel = destinationColorModel.createCompatibleSampleModel(image.getWidth(), image.getHeight()); layout.setColorModel(destinationColorModel); layout.setSampleModel(destinationSampleModel); // Lookup Operations image = LookupDescriptor.create(image, new LookupTableWrapper(lut), 0, null, null, false, hints); return image; }
public void setPixels( int x, int y, int w, int h, ColorModel model, byte pix[], int off, int scansize) { int lineOff = off; int poff; int[] newLUT = null; if (src != null) { src.checkSecurity(null, false); } // REMIND: What if the model doesn't fit in default color model? synchronized (this) { if (bimage == null) { if (cmodel == null) { cmodel = model; } createBufferedImage(); } if (w <= 0 || h <= 0) { return; } int biWidth = biRaster.getWidth(); int biHeight = biRaster.getHeight(); int x1 = x + w; // Overflow protection below int y1 = y + h; // Overflow protection below if (x < 0) { off -= x; x = 0; } else if (x1 < 0) { x1 = biWidth; // Must be overflow } if (y < 0) { off -= y * scansize; y = 0; } else if (y1 < 0) { y1 = biHeight; // Must be overflow } if (x1 > biWidth) { x1 = biWidth; } if (y1 > biHeight) { y1 = biHeight; } if (x >= x1 || y >= y1) { return; } // x,y,x1,y1 are all >= 0, so w,h must be >= 0 w = x1 - x; h = y1 - y; // off is first pixel read so it must be in bounds if (off < 0 || off >= pix.length) { // They overflowed their own array throw new ArrayIndexOutOfBoundsException("Data offset out of bounds."); } // pix.length and off are >= 0 so remainder >= 0 int remainder = pix.length - off; if (remainder < w) { // They overflowed their own array throw new ArrayIndexOutOfBoundsException("Data array is too short."); } int num; if (scansize < 0) { num = (off / -scansize) + 1; } else if (scansize > 0) { num = ((remainder - w) / scansize) + 1; } else { num = h; } if (h > num) { // They overflowed their own array. throw new ArrayIndexOutOfBoundsException("Data array is too short."); } if (isSameCM && (cmodel != model) && (srcLUT != null) && (model instanceof IndexColorModel) && (biRaster instanceof ByteComponentRaster)) { IndexColorModel icm = (IndexColorModel) model; ByteComponentRaster bct = (ByteComponentRaster) biRaster; int numlut = numSrcLUT; if (!setDiffICM( x, y, w, h, srcLUT, srcLUTtransIndex, numSrcLUT, icm, pix, off, scansize, bct, bct.getDataOffset(0))) { convertToRGB(); } else { // Note that setDiffICM modified the raster directly // so we must mark it as changed bct.markDirty(); if (numlut != numSrcLUT) { boolean hasAlpha = icm.hasAlpha(); if (srcLUTtransIndex != -1) { hasAlpha = true; } int nbits = icm.getPixelSize(); icm = new IndexColorModel( nbits, numSrcLUT, srcLUT, 0, hasAlpha, srcLUTtransIndex, (nbits > 8 ? DataBuffer.TYPE_USHORT : DataBuffer.TYPE_BYTE)); cmodel = icm; bimage = createImage(icm, bct, false, null); } return; } } if (isDefaultBI) { int pixel; IntegerComponentRaster iraster = (IntegerComponentRaster) biRaster; if (srcLUT != null && model instanceof IndexColorModel) { if (model != srcModel) { // Fill in the new lut ((IndexColorModel) model).getRGBs(srcLUT); srcModel = model; } if (s_useNative) { // Note that setICMpixels modifies the raster directly // so we must mark it as changed afterwards if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize, iraster)) { iraster.markDirty(); } else { abort(); return; } } else { int[] storage = new int[w * h]; int soff = 0; // It is an IndexColorModel for (int yoff = 0; yoff < h; yoff++, lineOff += scansize) { poff = lineOff; for (int i = 0; i < w; i++) { storage[soff++] = srcLUT[pix[poff++] & 0xff]; } } iraster.setDataElements(x, y, w, h, storage); } } else { int[] storage = new int[w]; for (int yoff = y; yoff < y + h; yoff++, lineOff += scansize) { poff = lineOff; for (int i = 0; i < w; i++) { storage[i] = model.getRGB(pix[poff++] & 0xff); } iraster.setDataElements(x, yoff, w, 1, storage); } availinfo |= ImageObserver.SOMEBITS; } } else if ((cmodel == model) && (biRaster instanceof ByteComponentRaster) && (biRaster.getNumDataElements() == 1)) { ByteComponentRaster bt = (ByteComponentRaster) biRaster; if (off == 0 && scansize == w) { bt.putByteData(x, y, w, h, pix); } else { byte[] bpix = new byte[w]; poff = off; for (int yoff = y; yoff < y + h; yoff++) { System.arraycopy(pix, poff, bpix, 0, w); bt.putByteData(x, yoff, w, 1, bpix); poff += scansize; } } } else { for (int yoff = y; yoff < y + h; yoff++, lineOff += scansize) { poff = lineOff; for (int xoff = x; xoff < x + w; xoff++) { bimage.setRGB(xoff, yoff, model.getRGB(pix[poff++] & 0xff)); } } availinfo |= ImageObserver.SOMEBITS; } } if ((availinfo & ImageObserver.FRAMEBITS) == 0) { newInfo(image, ImageObserver.SOMEBITS, x, y, w, h); } }
/* (non-Javadoc) * @see deadbeef.SupTools.SubtitleStream#decode(int) */ @Override public void decode(int index) throws CoreException { try { File f = new File(subPictures.get(index).getFileName()); if (!f.exists()) { throw new CoreException("file " + subPictures.get(index).getFileName() + " not found."); } BufferedImage img = ImageIO.read(f); int w = img.getWidth(); int h = img.getHeight(); this.palette = null; // first try to read image and palette directly from imported image if (img.getType() == BufferedImage.TYPE_BYTE_INDEXED) { IndexColorModel icm = (IndexColorModel) img.getColorModel(); if (icm.getMapSize() < 255 || (icm.hasAlpha() && icm.getAlpha(255) == 0)) { // create palette palette = new Palette(256); for (int i = 0; i < icm.getMapSize(); i++) { int alpha = (icm.getRGB(i) >> 24) & 0xff; if (alpha >= configuration.getAlphaCrop()) { palette.setARGB(i, icm.getRGB(i)); } else { palette.setARGB(i, 0); } } // copy pixels WritableRaster raster = img.getRaster(); bitmap = new Bitmap( img.getWidth(), img.getHeight(), (byte[]) raster.getDataElements(0, 0, img.getWidth(), img.getHeight(), null)); } } // if this failed, assume RGB image and quantize palette if (palette == null) { // grab int array (ARGB) int[] pixels = new int[w * h]; img.getRGB(0, 0, w, h, pixels, 0, w); // quantize image QuantizeFilter qf = new QuantizeFilter(); bitmap = new Bitmap(img.getWidth(), img.getHeight()); int ct[] = qf.quantize(pixels, bitmap.getInternalBuffer(), w, h, 255, false, false); int size = ct.length; if (size > 255) { logger.warn("Quantizer failed.\n"); size = 255; } // create palette palette = new Palette(256); for (int i = 0; i < size; i++) { int alpha = (ct[i] >> 24) & 0xff; if (alpha >= configuration.getAlphaCrop()) { palette.setARGB(i, ct[i]); } else { palette.setARGB(i, 0); } } } primaryColorIndex = bitmap.getPrimaryColorIndex( palette.getAlpha(), configuration.getAlphaThreshold(), palette.getY()); // crop BitmapBounds bounds = bitmap.getCroppingBounds(palette.getAlpha(), configuration.getAlphaCrop()); if (bounds.yMin > 0 || bounds.xMin > 0 || bounds.xMax < bitmap.getWidth() - 1 || bounds.yMax < bitmap.getHeight() - 1) { w = bounds.xMax - bounds.xMin + 1; h = bounds.yMax - bounds.yMin + 1; if (w < 2) { w = 2; } if (h < 2) { h = 2; } bitmap = bitmap.crop(bounds.xMin, bounds.yMin, w, h); // update picture SubPictureXml pic = subPictures.get(index); pic.setImageWidth(w); pic.setImageHeight(h); pic.setOfsX(pic.getOriginalXOffset() + bounds.xMin); pic.setOfsY(pic.getOriginalYOffset() + bounds.yMin); } } catch (IOException e) { throw new CoreException(e.getMessage()); } catch (OutOfMemoryError e) { JOptionPane.showMessageDialog( null, "Out of heap! Use -Xmx256m to increase heap!", "Error!", JOptionPane.WARNING_MESSAGE); throw new CoreException("Out of heap! Use -Xmx256m to increase heap!"); } }