📄 jpegmetadata.java
字号:
for (int i = 0; iter.hasNext(); i++) { MarkerSegment seg = (MarkerSegment)iter.next(); if (cls.isInstance(seg)) { return i; } } } else { ListIterator iter = markerSequence.listIterator(markerSequence.size()); for (int i = markerSequence.size()-1; iter.hasPrevious(); i--) { MarkerSegment seg = (MarkerSegment)iter.previous(); if (cls.isInstance(seg)) { return i; } } } return -1; } private int findLastUnknownMarkerSegmentPosition() { ListIterator iter = markerSequence.listIterator(markerSequence.size()); for (int i = markerSequence.size()-1; iter.hasPrevious(); i--) { MarkerSegment seg = (MarkerSegment)iter.previous(); if (seg.unknown == true) { return i; } } return -1; } // Implement Cloneable, but restrict access protected Object clone() { JPEGMetadata newGuy = null; try { newGuy = (JPEGMetadata) super.clone(); } catch (CloneNotSupportedException e) {} // won't happen if (markerSequence != null) { newGuy.markerSequence = (List) cloneSequence(); } newGuy.resetSequence = null; return newGuy; } /** * Returns a deep copy of the current marker sequence. */ private List cloneSequence() { if (markerSequence == null) { return null; } List retval = new ArrayList(markerSequence.size()); Iterator iter = markerSequence.iterator(); while(iter.hasNext()) { MarkerSegment seg = (MarkerSegment)iter.next(); retval.add(seg.clone()); } return retval; } // Tree methods public Node getAsTree(String formatName) { if (formatName == null) { throw new IllegalArgumentException("null formatName!"); } if (isStream) { if (formatName.equals(JPEG.nativeStreamMetadataFormatName)) { return getNativeTree(); } } else { if (formatName.equals(JPEG.nativeImageMetadataFormatName)) { return getNativeTree(); } if (formatName.equals (IIOMetadataFormatImpl.standardMetadataFormatName)) { return getStandardTree(); } } throw new IllegalArgumentException("Unsupported format name: " + formatName); } IIOMetadataNode getNativeTree() { IIOMetadataNode root; IIOMetadataNode top; Iterator iter = markerSequence.iterator(); if (isStream) { root = new IIOMetadataNode(JPEG.nativeStreamMetadataFormatName); top = root; } else { IIOMetadataNode sequence = new IIOMetadataNode("markerSequence"); if (!inThumb) { root = new IIOMetadataNode(JPEG.nativeImageMetadataFormatName); IIOMetadataNode header = new IIOMetadataNode("JPEGvariety"); root.appendChild(header); JFIFMarkerSegment jfif = (JFIFMarkerSegment) findMarkerSegment(JFIFMarkerSegment.class, true); if (jfif != null) { iter.next(); // JFIF must be first, so this skips it header.appendChild(jfif.getNativeNode()); } root.appendChild(sequence); } else { root = sequence; } top = sequence; } while(iter.hasNext()) { MarkerSegment seg = (MarkerSegment) iter.next(); top.appendChild(seg.getNativeNode()); } return root; } // Standard tree node methods protected IIOMetadataNode getStandardChromaNode() { hasAlpha = false; // Unless we find otherwise // Colorspace type - follow the rules in the spec // First get the SOF marker segment, if there is one SOFMarkerSegment sof = (SOFMarkerSegment) findMarkerSegment(SOFMarkerSegment.class, true); if (sof == null) { // No image, so no chroma return null; } IIOMetadataNode chroma = new IIOMetadataNode("Chroma"); IIOMetadataNode csType = new IIOMetadataNode("ColorSpaceType"); chroma.appendChild(csType); // get the number of channels int numChannels = sof.componentSpecs.length; IIOMetadataNode numChanNode = new IIOMetadataNode("NumChannels"); chroma.appendChild(numChanNode); numChanNode.setAttribute("value", Integer.toString(numChannels)); // is there a JFIF marker segment? if (findMarkerSegment(JFIFMarkerSegment.class, true) != null) { if (numChannels == 1) { csType.setAttribute("name", "GRAY"); } else { csType.setAttribute("name", "YCbCr"); } return chroma; } // How about an Adobe marker segment? AdobeMarkerSegment adobe = (AdobeMarkerSegment) findMarkerSegment(AdobeMarkerSegment.class, true); if (adobe != null){ switch (adobe.transform) { case JPEG.ADOBE_YCCK: csType.setAttribute("name", "YCCK"); break; case JPEG.ADOBE_YCC: csType.setAttribute("name", "YCbCr"); break; case JPEG.ADOBE_UNKNOWN: if (numChannels == 3) { csType.setAttribute("name", "RGB"); } else if (numChannels == 4) { csType.setAttribute("name", "CMYK"); } break; } return chroma; } // Neither marker. Check components if (numChannels < 3) { csType.setAttribute("name", "GRAY"); if (numChannels == 2) { hasAlpha = true; } return chroma; } boolean idsAreJFIF = true; for (int i = 0; i < sof.componentSpecs.length; i++) { int id = sof.componentSpecs[i].componentId; if ((id < 1) || (id >= sof.componentSpecs.length)) { idsAreJFIF = false; } } if (idsAreJFIF) { csType.setAttribute("name", "YCbCr"); if (numChannels == 4) { hasAlpha = true; } return chroma; } // Check against the letters if ((sof.componentSpecs[0].componentId == 'R') && (sof.componentSpecs[1].componentId == 'G') && (sof.componentSpecs[2].componentId == 'B')){ csType.setAttribute("name", "RGB"); if ((numChannels == 4) && (sof.componentSpecs[3].componentId == 'A')) { hasAlpha = true; } return chroma; } if ((sof.componentSpecs[0].componentId == 'Y') && (sof.componentSpecs[1].componentId == 'C') && (sof.componentSpecs[2].componentId == 'c')){ csType.setAttribute("name", "PhotoYCC"); if ((numChannels == 4) && (sof.componentSpecs[3].componentId == 'A')) { hasAlpha = true; } return chroma; } // Finally, 3-channel subsampled are YCbCr, unsubsampled are RGB // 4-channel subsampled are YCbCrA, unsubsampled are CMYK boolean subsampled = false; int hfactor = sof.componentSpecs[0].HsamplingFactor; int vfactor = sof.componentSpecs[0].VsamplingFactor; for (int i = 1; i<sof.componentSpecs.length; i++) { if ((sof.componentSpecs[i].HsamplingFactor != hfactor) || (sof.componentSpecs[i].VsamplingFactor != vfactor)){ subsampled = true; break; } } if (subsampled) { csType.setAttribute("name", "YCbCr"); if (numChannels == 4) { hasAlpha = true; } return chroma; } // Not subsampled. numChannels < 3 is taken care of above if (numChannels == 3) { csType.setAttribute("name", "RGB"); } else { csType.setAttribute("name", "CMYK"); } return chroma; } protected IIOMetadataNode getStandardCompressionNode() { IIOMetadataNode compression = new IIOMetadataNode("Compression"); // CompressionTypeName IIOMetadataNode name = new IIOMetadataNode("CompressionTypeName"); name.setAttribute("value", "JPEG"); compression.appendChild(name); // Lossless - false IIOMetadataNode lossless = new IIOMetadataNode("Lossless"); lossless.setAttribute("value", "false"); compression.appendChild(lossless); // NumProgressiveScans - count sos segments int sosCount = 0; Iterator iter = markerSequence.iterator(); while (iter.hasNext()) { MarkerSegment ms = (MarkerSegment) iter.next(); if (ms.tag == JPEG.SOS) { sosCount++; } } if (sosCount != 0) { IIOMetadataNode prog = new IIOMetadataNode("NumProgressiveScans"); prog.setAttribute("value", Integer.toString(sosCount)); compression.appendChild(prog); } return compression; } protected IIOMetadataNode getStandardDimensionNode() { // If we have a JFIF marker segment, we know a little // otherwise all we know is the orientation, which is always normal IIOMetadataNode dim = new IIOMetadataNode("Dimension"); IIOMetadataNode orient = new IIOMetadataNode("ImageOrientation"); orient.setAttribute("value", "normal"); dim.appendChild(orient); JFIFMarkerSegment jfif = (JFIFMarkerSegment) findMarkerSegment(JFIFMarkerSegment.class, true); if (jfif != null) { // Aspect Ratio is width of pixel / height of pixel float aspectRatio; if (jfif.resUnits == 0) { // In this case they just encode aspect ratio directly aspectRatio = ((float) jfif.Xdensity)/jfif.Ydensity; } else { // They are true densities (e.g. dpi) and must be inverted aspectRatio = ((float) jfif.Ydensity)/jfif.Xdensity; } IIOMetadataNode aspect = new IIOMetadataNode("PixelAspectRatio"); aspect.setAttribute("value", Float.toString(aspectRatio)); dim.insertBefore(aspect, orient); // Pixel size if (jfif.resUnits != 0) { // 1 == dpi, 2 == dpc float scale = (jfif.resUnits == 1) ? 25.4F : 10.0F; IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize"); horiz.setAttribute("value", Float.toString(scale/jfif.Xdensity)); dim.appendChild(horiz); IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize"); vert.setAttribute("value", Float.toString(scale/jfif.Ydensity)); dim.appendChild(vert); } } return dim; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -