Esempio n. 1
0
  public ColorModel createColorModel() {
    int[] bits;
    if (hasAlpha) bits = new int[cspace.getNumComponents() + 1];
    else bits = new int[cspace.getNumComponents()];
    Arrays.fill(bits, 8);

    return new ComponentColorModel(cspace, bits, hasAlpha, alphaPre, transparency, transferType);
  }
  // Create an appropriate array of bits, given a colorspace (ie, number of
  // bands), size of the storage data type, and presence of an alpha band.
  private static int[] findBits(ColorSpace colorSpace, int transferType, boolean hasAlpha) {
    int[] bits;
    if (hasAlpha) bits = new int[colorSpace.getNumComponents() + 1];
    else bits = new int[colorSpace.getNumComponents()];

    Arrays.fill(bits, DataBuffer.getDataTypeSize(transferType));

    return bits;
  }
Esempio n. 3
0
 /**
  * Creates a color in the specified <code>ColorSpace</code> with the color components specified in
  * the <code>float</code> array and the specified alpha. The number of components is determined by
  * the type of the <code>ColorSpace</code>. For example, RGB requires 3 components, but CMYK
  * requires 4 components.
  *
  * @param cspace the <code>ColorSpace</code> to be used to interpret the components
  * @param components an arbitrary number of color components that is compatible with the <code>
  *     ColorSpace</code>
  * @param alpha alpha value
  * @throws IllegalArgumentException if any of the values in the <code>components</code> array or
  *     <code>alpha</code> is outside of the range supported by cspace.
  * @see #getComponents
  * @see #getColorComponents
  */
 public CompositeColor(ColorSpace cspace, float components[], float alpha) {
   super(((int) (alpha * 255) << 24) | ColorUtil.toRGB24(cspace, components), true);
   boolean rangeError = false;
   StringBuilder badComponentString = new StringBuilder();
   int n = cspace.getNumComponents();
   fvalue = new float[n];
   for (int i = 0; i < n; i++) {
     if (components[i] < cspace.getMinValue(i) || components[i] > cspace.getMaxValue(i)) {
       rangeError = true;
       badComponentString.append("Component ");
       badComponentString.append(i);
       badComponentString.append(' ');
     } else {
       fvalue[i] = components[i];
     }
   }
   if (alpha < 0.0 || alpha > 1.0) {
     rangeError = true;
     badComponentString.append("Alpha");
   } else {
     falpha = alpha;
   }
   if (rangeError) {
     throw new IllegalArgumentException(
         "Color parameter outside of expected range: " + badComponentString);
   }
   cs = cspace;
 }
Esempio n. 4
0
 private static int calculateColor(float[] f, ColorSpace colorSpace) {
   int n = colorSpace.getNumComponents();
   // Get the reverse of f, and only take n values
   // Might as well limit the bounds while we're at it
   float[] fvalue = new float[n];
   int toCopy = n;
   int fLength = f.length;
   if (fLength < toCopy) {
     toCopy = fLength;
   }
   for (int i = 0; i < toCopy; i++) {
     float curr = f[fLength - 1 - i];
     if (curr < 0.0f) {
       curr = 0.0f;
     } else if (curr > 1.0f) {
       curr = 1.0f;
     }
     fvalue[i] = curr;
   }
   float[] frgbvalue = colorSpace.toRGB(fvalue);
   return (0xFF000000)
       | ((((int) (frgbvalue[0] * 255)) & 0xFF) << 16)
       | ((((int) (frgbvalue[1] * 255)) & 0xFF) << 8)
       | ((((int) (frgbvalue[2] * 255)) & 0xFF));
 }
Esempio n. 5
0
  private ICC_Profile buildICCProfile(
      final ImageInfo info, final ColorSpace colorSpace, final ByteArrayOutputStream iccStream)
      throws IOException {
    if (iccStream != null && iccStream.size() > 0) {
      if (log.isDebugEnabled()) {
        log.debug("Effective ICC profile size: " + iccStream.size());
      }
      final int alignment = 4;
      final int padding = (alignment - iccStream.size() % alignment) % alignment;
      if (padding != 0) {
        try {
          iccStream.write(new byte[padding]);
        } catch (final IOException ioe) {
          throw new IOException("Error while aligning ICC stream: " + ioe.getMessage());
        }
      }

      ICC_Profile iccProfile = null;
      try {
        iccProfile = ColorProfileUtil.getICC_Profile(iccStream.toByteArray());
        if (log.isDebugEnabled()) {
          log.debug("JPEG has an ICC profile: " + iccProfile.toString());
        }
      } catch (final IllegalArgumentException iae) {
        log.warn(
            "An ICC profile is present in the JPEG file but it is invalid ("
                + iae.getMessage()
                + "). The color profile will be ignored. ("
                + info.getOriginalURI()
                + ")");
        return null;
      }
      if (iccProfile.getNumComponents() != colorSpace.getNumComponents()) {
        log.warn(
            "The number of components of the ICC profile ("
                + iccProfile.getNumComponents()
                + ") doesn't match the image ("
                + colorSpace.getNumComponents()
                + "). Ignoring the ICC color profile.");
        return null;
      } else {
        return iccProfile;
      }
    } else {
      return null; // no ICC profile available
    }
  }
Esempio n. 6
0
  public Iterator getImageTypes(int imageIndex) throws IIOException {
    List l; // List of ImageTypeSpecifiers

    Integer imageIndexInteger = new Integer(imageIndex);
    if (imageTypeMap.containsKey(imageIndexInteger)) {
      // Return the cached ITS List.
      l = (List) imageTypeMap.get(imageIndexInteger);
    } else {
      // Create a new ITS List.
      l = new ArrayList(1);

      // Create the ITS and cache if for later use so that this method
      // always returns an Iterator containing the same ITS objects.
      seekToImage(imageIndex);
      ImageTypeSpecifier itsRaw =
          TIFFDecompressor.getRawImageTypeSpecifier(
              photometricInterpretation,
              compression,
              samplesPerPixel,
              bitsPerSample,
              sampleFormat,
              extraSamples,
              colorMap);

      // Check for an ICCProfile field.
      TIFFField iccProfileField = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_ICC_PROFILE);

      // If an ICCProfile field is present change the ImageTypeSpecifier
      // to use it if the data layout is component type.
      if (iccProfileField != null && itsRaw.getColorModel() instanceof ComponentColorModel) {
        // Create a ColorSpace from the profile.
        byte[] iccProfileValue = iccProfileField.getAsBytes();
        ICC_Profile iccProfile = ICC_Profile.getInstance(iccProfileValue);
        ICC_ColorSpace iccColorSpace = new ICC_ColorSpace(iccProfile);

        // Get the raw sample and color information.
        ColorModel cmRaw = itsRaw.getColorModel();
        ColorSpace csRaw = cmRaw.getColorSpace();
        SampleModel smRaw = itsRaw.getSampleModel();

        // Get the number of samples per pixel and the number
        // of color components.
        int numBands = smRaw.getNumBands();
        int numComponents = iccColorSpace.getNumComponents();

        // Replace the ColorModel with the ICC ColorModel if the
        // numbers of samples and color components are amenable.
        if (numBands == numComponents || numBands == numComponents + 1) {
          // Set alpha flags.
          boolean hasAlpha = numComponents != numBands;
          boolean isAlphaPre = hasAlpha && cmRaw.isAlphaPremultiplied();

          // Create a ColorModel of the same class and with
          // the same transfer type.
          ColorModel iccColorModel =
              new ComponentColorModel(
                  iccColorSpace,
                  cmRaw.getComponentSize(),
                  hasAlpha,
                  isAlphaPre,
                  cmRaw.getTransparency(),
                  cmRaw.getTransferType());

          // Prepend the ICC profile-based ITS to the List. The
          // ColorModel and SampleModel are guaranteed to be
          // compatible as the old and new ColorModels are both
          // ComponentColorModels with the same transfer type
          // and the same number of components.
          l.add(new ImageTypeSpecifier(iccColorModel, smRaw));

          // Append the raw ITS to the List if and only if its
          // ColorSpace has the same type and number of components
          // as the ICC ColorSpace.
          if (csRaw.getType() == iccColorSpace.getType()
              && csRaw.getNumComponents() == iccColorSpace.getNumComponents()) {
            l.add(itsRaw);
          }
        } else { // ICCProfile not compatible with SampleModel.
          // Append the raw ITS to the List.
          l.add(itsRaw);
        }
      } else { // No ICCProfile field or raw ColorModel not component.
        // Append the raw ITS to the List.
        l.add(itsRaw);
      }

      // Cache the ITS List.
      imageTypeMap.put(imageIndexInteger, l);
    }

    return l.iterator();
  }
Esempio n. 7
0
  /**
   * get a Java ColorModel consistent with the current color space, number of bits per component and
   * decode array
   *
   * @param bpc the number of bits per component
   */
  private ColorModel getColorModel() {
    PDFColorSpace cs = getColorSpace();

    if (cs instanceof IndexedColor) {
      IndexedColor ics = (IndexedColor) cs;

      byte[] components = ics.getColorComponents();
      int num = ics.getCount();

      // process the decode array
      if (this.decode != null) {
        byte[] normComps = new byte[components.length];

        // move the components array around
        for (int i = 0; i < num; i++) {
          byte[] orig = new byte[1];
          orig[0] = (byte) i;

          float[] res = normalize(orig, null, 0);
          int idx = (int) res[0];

          normComps[i * 3] = components[idx * 3];
          normComps[(i * 3) + 1] = components[(idx * 3) + 1];
          normComps[(i * 3) + 2] = components[(idx * 3) + 2];
        }

        components = normComps;
      }

      // make sure the size of the components array is 2 ^ numBits
      // since if it's not, Java will complain
      int correctCount = 1 << getBitsPerComponent();
      if (correctCount < num) {
        byte[] fewerComps = new byte[correctCount * 3];

        System.arraycopy(components, 0, fewerComps, 0, correctCount * 3);

        components = fewerComps;
        num = correctCount;
      }
      if (this.colorKeyMask == null || this.colorKeyMask.length == 0) {
        return new IndexColorModel(getBitsPerComponent(), num, components, 0, false);
      } else {
        byte[] aComps = new byte[num * 4];
        int idx = 0;
        for (int i = 0; i < num; i++) {
          aComps[idx++] = components[(i * 3)];
          aComps[idx++] = components[(i * 3) + 1];
          aComps[idx++] = components[(i * 3) + 2];
          aComps[idx++] = (byte) 0xFF;
        }
        for (int i = 0; i < this.colorKeyMask.length; i += 2) {
          for (int j = this.colorKeyMask[i]; j <= this.colorKeyMask[i + 1]; j++) {
            aComps[(j * 4) + 3] = 0; // make transparent
          }
        }
        return new IndexColorModel(getBitsPerComponent(), num, aComps, 0, true);
      }
    } else if (cs instanceof AlternateColorSpace) {
      ColorSpace altCS =
          new AltColorSpace(((AlternateColorSpace) cs).getFunktion(), cs.getColorSpace());
      int[] bits = new int[altCS.getNumComponents()];
      for (int i = 0; i < bits.length; i++) {
        bits[i] = getBitsPerComponent();
      }
      return new DecodeComponentColorModel(altCS, bits);
    } else {
      // CMYK color space has been converted to RGB in DCTDecode
      if (cs.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
        ColorSpace rgbCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
        int[] bits = new int[rgbCS.getNumComponents()];
        for (int i = 0; i < bits.length; i++) {
          bits[i] = getBitsPerComponent();
        }
        return new DecodeComponentColorModel(rgbCS, bits);
      }
      int[] bits = new int[cs.getNumComponents()];
      for (int i = 0; i < bits.length; i++) {
        bits[i] = getBitsPerComponent();
      }

      return new DecodeComponentColorModel(cs.getColorSpace(), bits);
    }
  }