📄 jpegimagewriter.java
字号:
* must not be for a progressive image, or an exception * will be thrown when two Huffman tables with the same * table id are encountered. */ private JPEGHuffmanTable[] collectHTablesFromMetadata (JPEGMetadata metadata, boolean wantDC) throws IIOException { ArrayList tables = new ArrayList(); Iterator iter = metadata.markerSequence.iterator(); while (iter.hasNext()) { MarkerSegment seg = (MarkerSegment) iter.next(); if (seg instanceof DHTMarkerSegment) { DHTMarkerSegment dht = (DHTMarkerSegment) seg; for (int i = 0; i < dht.tables.size(); i++) { DHTMarkerSegment.Htable htable = (DHTMarkerSegment.Htable) dht.tables.get(i); if (htable.tableClass == (wantDC ? 0 : 1)) { tables.add(htable); } } } } JPEGHuffmanTable [] retval = null; if (tables.size() != 0) { DHTMarkerSegment.Htable [] htables = new DHTMarkerSegment.Htable[tables.size()]; tables.toArray(htables); retval = new JPEGHuffmanTable[tables.size()]; for (int i = 0; i < retval.length; i++) { retval[i] = null; for (int j = 0; j < tables.size(); j++) { if (htables[j].tableID == i) { if (retval[i] != null) { throw new IIOException("Metadata has duplicate Htables!"); } retval[i] = new JPEGHuffmanTable(htables[j].numCodes, htables[j].values); } } } } return retval; } /////////// End of metadata handling ////////////// ColorSpace conversion private int getSrcCSType(RenderedImage rimage) { int retval = JPEG.JCS_UNKNOWN; ColorModel cm = rimage.getColorModel(); if (cm != null) { boolean alpha = cm.hasAlpha(); ColorSpace cs = cm.getColorSpace(); switch (cs.getType()) { case ColorSpace.TYPE_GRAY: retval = JPEG.JCS_GRAYSCALE; break; case ColorSpace.TYPE_RGB: if (alpha) { retval = JPEG.JCS_RGBA; } else { retval = JPEG.JCS_RGB; } break; case ColorSpace.TYPE_YCbCr: if (alpha) { retval = JPEG.JCS_YCbCrA; } else { retval = JPEG.JCS_YCbCr; } break; case ColorSpace.TYPE_3CLR: if (cs == JPEG.YCC) { if (alpha) { retval = JPEG.JCS_YCCA; } else { retval = JPEG.JCS_YCC; } } case ColorSpace.TYPE_CMYK: retval = JPEG.JCS_CMYK; break; } } return retval; } private int getDestCSType(ImageTypeSpecifier destType) { ColorModel cm = destType.getColorModel(); boolean alpha = cm.hasAlpha(); ColorSpace cs = cm.getColorSpace(); int retval = JPEG.JCS_UNKNOWN; switch (cs.getType()) { case ColorSpace.TYPE_GRAY: retval = JPEG.JCS_GRAYSCALE; break; case ColorSpace.TYPE_RGB: if (alpha) { retval = JPEG.JCS_RGBA; } else { retval = JPEG.JCS_RGB; } break; case ColorSpace.TYPE_YCbCr: if (alpha) { retval = JPEG.JCS_YCbCrA; } else { retval = JPEG.JCS_YCbCr; } break; case ColorSpace.TYPE_3CLR: if (cs == JPEG.YCC) { if (alpha) { retval = JPEG.JCS_YCCA; } else { retval = JPEG.JCS_YCC; } } case ColorSpace.TYPE_CMYK: retval = JPEG.JCS_CMYK; break; } return retval; } private int getDefaultDestCSType(RenderedImage rimage) { int retval = JPEG.JCS_UNKNOWN; ColorModel cm = rimage.getColorModel(); if (cm != null) { boolean alpha = cm.hasAlpha(); ColorSpace cs = cm.getColorSpace(); switch (cs.getType()) { case ColorSpace.TYPE_GRAY: retval = JPEG.JCS_GRAYSCALE; break; case ColorSpace.TYPE_RGB: if (alpha) { retval = JPEG.JCS_YCbCrA; } else { retval = JPEG.JCS_YCbCr; } break; case ColorSpace.TYPE_YCbCr: if (alpha) { retval = JPEG.JCS_YCbCrA; } else { retval = JPEG.JCS_YCbCr; } break; case ColorSpace.TYPE_3CLR: if (cs == JPEG.YCC) { if (alpha) { retval = JPEG.JCS_YCCA; } else { retval = JPEG.JCS_YCC; } } case ColorSpace.TYPE_CMYK: retval = JPEG.JCS_YCCK; break; } } return retval; } private boolean isSubsampled(SOFMarkerSegment.ComponentSpec [] specs) { int hsamp0 = specs[0].HsamplingFactor; int vsamp0 = specs[0].VsamplingFactor; for (int i = 1; i < specs.length; i++) { if ((specs[i].HsamplingFactor != hsamp0) || (specs[i].HsamplingFactor != hsamp0)) return true; } return false; } ////////////// End of ColorSpace conversion ////////////// Native methods and callbacks /** Sets up static native structures. */ private static native void initWriterIDs(Class iosClass, Class qTableClass, Class huffClass); /** Sets up per-writer native structure and returns a pointer to it. */ private native long initJPEGImageWriter(); /** Sets up native structures for output stream */ private native void setDest(long structPointer, ImageOutputStream ios); /** * Returns <code>true</code> if the write was aborted. */ private native boolean writeImage(long structPointer, byte [] data, int inCsType, int outCsType, int numBands, int [] bandSizes, int srcWidth, int destWidth, int destHeight, int stepX, int stepY, JPEGQTable [] qtables, boolean writeDQT, JPEGHuffmanTable[] DCHuffmanTables, JPEGHuffmanTable[] ACHuffmanTables, boolean writeDHT, boolean optimizeHuffman, boolean progressive, int numScans, int [] scans, int [] componentIds, int [] HsamplingFactors, int [] VsamplingFactors, int [] QtableSelectors, boolean haveMetadata, int restartInterval); /** * Writes the metadata out when called by the native code, * which will have already written the header to the stream * and established the library state. This is simpler than * breaking the write call in two. */ private void writeMetadata() throws IOException { if (metadata == null) { if (writeDefaultJFIF) { JFIFMarkerSegment.writeDefaultJFIF(ios, thumbnails, iccProfile, this); } if (writeAdobe) { AdobeMarkerSegment.writeAdobeSegment(ios, newAdobeTransform); } } else { metadata.writeToStream(ios, ignoreJFIF, forceJFIF, thumbnails, iccProfile, ignoreAdobe, newAdobeTransform, this); } } /** * Write out a tables-only image to the stream. */ private native void writeTables(long structPointer, JPEGQTable [] qtables, JPEGHuffmanTable[] DCHuffmanTables, JPEGHuffmanTable[] ACHuffmanTables); /** * Put the scanline y of the source ROI view Raster into the * 1-line Raster for writing. This handles ROI and band * rearrangements, and expands indexed images. Subsampling is * done in the native code. * This is called by the native code. */ private void grabPixels(int y) { Raster sourceLine = null; if (indexed) { sourceLine = srcRas.createChild(sourceXOffset, sourceYOffset+y, sourceWidth, 1, 0, 0, new int [] {0}); // If the image has BITMASK transparency, we need to make sure // it gets converted to 32-bit ARGB, because the JPEG encoder // relies upon the full 8-bit alpha channel. boolean forceARGB = (indexCM.getTransparency() != Transparency.OPAQUE); BufferedImage temp = indexCM.convertToIntDiscrete(sourceLine, forceARGB); sourceLine = temp.getRaster(); } else { sourceLine = srcRas.createChild(sourceXOffset, sourceYOffset+y, sourceWidth, 1, 0, 0, srcBands); } if (convertTosRGB) { if (debug) { System.out.println("Converting to sRGB"); } // The first time through, converted is null, so // a new raster is allocated. It is then reused // on subsequent lines. converted = convertOp.filter(sourceLine, converted); sourceLine = converted; } raster.setRect(sourceLine); if ((y > 7) && (y%8 == 0)) { // Every 8 scanlines processImageProgress((float) y / (float) sourceHeight * 100.0F); } } /** Aborts the current write in the native code */ private native void abortWrite(long structPointer); /** Resets native structures */ private native void resetWriter(long structPointer); /** Releases native structures */ private native void disposeWriter(long structPointer);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -