示例#1
0
  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);
    }
  }
示例#4
0
  /* (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!");
    }
  }