Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 765E9104E6 for ; Sun, 11 Jan 2015 12:33:53 +0000 (UTC) Received: (qmail 45111 invoked by uid 500); 11 Jan 2015 12:33:39 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 44920 invoked by uid 500); 11 Jan 2015 12:33:39 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 41669 invoked by uid 99); 11 Jan 2015 12:33:36 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 11 Jan 2015 12:33:36 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id C2228AC0A00 for ; Sun, 11 Jan 2015 12:33:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r935812 [35/46] - in /websites/production/commons/content/proper/commons-imaging: ./ apidocs/ apidocs/org/apache/commons/imaging/ apidocs/org/apache/commons/imaging/class-use/ apidocs/org/apache/commons/imaging/color/ apidocs/org/apache/com... Date: Sun, 11 Jan 2015 12:33:28 -0000 To: commits@commons.apache.org From: britter@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150111123334.C2228AC0A00@hades.apache.org> Modified: websites/production/commons/content/proper/commons-imaging/xref/org/apache/commons/imaging/formats/gif/GifImageParser.html ============================================================================== --- websites/production/commons/content/proper/commons-imaging/xref/org/apache/commons/imaging/formats/gif/GifImageParser.html (original) +++ websites/production/commons/content/proper/commons-imaging/xref/org/apache/commons/imaging/formats/gif/GifImageParser.html Sun Jan 11 12:33:25 2015 @@ -504,602 +504,603 @@ 496 return new Dimension(id.imageWidth, id.imageHeight); 497 } 498 -499 @Override -500 public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) -501 throws ImageReadException, IOException { -502 return null; -503 } -504 -505 private List<String> getComments(final List<GifBlock> blocks) throws IOException { -506 final List<String> result = new ArrayList<String>(); -507 final int code = 0x21fe; -508 -509 for (GifBlock block : blocks) { -510 if (block.blockCode == code) { -511 final byte[] bytes = ((GenericGifBlock) block).appendSubBlocks(); -512 result.add(new String(bytes, "US-ASCII")); -513 } -514 } -515 -516 return result; -517 } -518 -519 @Override -520 public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) -521 throws ImageReadException, IOException { -522 final ImageContents blocks = readFile(byteSource, false); -523 -524 if (blocks == null) { -525 throw new ImageReadException("GIF: Couldn't read blocks"); -526 } -527 -528 final GifHeaderInfo bhi = blocks.gifHeaderInfo; -529 if (bhi == null) { -530 throw new ImageReadException("GIF: Couldn't read Header"); -531 } -532 -533 final ImageDescriptor id = (ImageDescriptor) findBlock(blocks.blocks, -534 IMAGE_SEPARATOR); -535 if (id == null) { -536 throw new ImageReadException("GIF: Couldn't read ImageDescriptor"); -537 } -538 -539 final GraphicControlExtension gce = (GraphicControlExtension) findBlock( -540 blocks.blocks, GRAPHIC_CONTROL_EXTENSION); -541 -542 // Prefer the size information in the ImageDescriptor; it is more -543 // reliable than the size information in the header. -544 final int height = id.imageHeight; -545 final int width = id.imageWidth; -546 -547 final List<String> comments = getComments(blocks.blocks); -548 final int bitsPerPixel = (bhi.colorResolution + 1); -549 final ImageFormat format = ImageFormats.GIF; -550 final String formatName = "GIF Graphics Interchange Format"; -551 final String mimeType = "image/gif"; -552 // we ought to count images, but don't yet. -553 final int numberOfImages = -1; -554 -555 final boolean progressive = id.interlaceFlag; -556 -557 final int physicalWidthDpi = 72; -558 final float physicalWidthInch = (float) ((double) width / (double) physicalWidthDpi); -559 final int physicalHeightDpi = 72; -560 final float physicalHeightInch = (float) ((double) height / (double) physicalHeightDpi); -561 -562 final String formatDetails = "Gif " + ((char) blocks.gifHeaderInfo.version1) -563 + ((char) blocks.gifHeaderInfo.version2) -564 + ((char) blocks.gifHeaderInfo.version3); -565 -566 boolean transparent = false; -567 if (gce != null && gce.transparency) { -568 transparent = true; -569 } -570 -571 final boolean usesPalette = true; -572 final ImageInfo.ColorType colorType = ImageInfo.ColorType.RGB; -573 final ImageInfo.CompressionAlgorithm compressionAlgorithm = ImageInfo.CompressionAlgorithm.LZW; -574 -575 return new ImageInfo(formatDetails, bitsPerPixel, comments, -576 format, formatName, height, mimeType, numberOfImages, -577 physicalHeightDpi, physicalHeightInch, physicalWidthDpi, -578 physicalWidthInch, width, progressive, transparent, -579 usesPalette, colorType, compressionAlgorithm); -580 } -581 -582 @Override -583 public boolean dumpImageFile(final PrintWriter pw, final ByteSource byteSource) -584 throws ImageReadException, IOException { -585 pw.println("gif.dumpImageFile"); -586 -587 final ImageInfo imageData = getImageInfo(byteSource); -588 if (imageData == null) { -589 return false; -590 } -591 -592 imageData.toString(pw, ""); -593 -594 final ImageContents blocks = readFile(byteSource, false); -595 -596 pw.println("gif.blocks: " + blocks.blocks.size()); -597 for (int i = 0; i < blocks.blocks.size(); i++) { -598 final GifBlock gifBlock = blocks.blocks.get(i); -599 this.debugNumber(pw, "\t" + i + " (" -600 + gifBlock.getClass().getName() + ")", -601 gifBlock.blockCode, 4); -602 } -603 -604 pw.println(""); -605 -606 return true; -607 } -608 -609 private int[] getColorTable(final byte[] bytes) throws ImageReadException { -610 if ((bytes.length % 3) != 0) { -611 throw new ImageReadException("Bad Color Table Length: " -612 + bytes.length); -613 } -614 final int length = bytes.length / 3; -615 -616 final int[] result = new int[length]; -617 -618 for (int i = 0; i < length; i++) { -619 final int red = 0xff & bytes[(i * 3) + 0]; -620 final int green = 0xff & bytes[(i * 3) + 1]; -621 final int blue = 0xff & bytes[(i * 3) + 2]; -622 -623 final int alpha = 0xff; -624 -625 final int rgb = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0); -626 result[i] = rgb; -627 } -628 -629 return result; -630 } -631 -632 @Override -633 public FormatCompliance getFormatCompliance(final ByteSource byteSource) -634 throws ImageReadException, IOException { -635 final FormatCompliance result = new FormatCompliance( -636 byteSource.getDescription()); -637 -638 readFile(byteSource, false, result); -639 -640 return result; -641 } -642 -643 @Override -644 public BufferedImage getBufferedImage(final ByteSource byteSource, final Map<String, Object> params) -645 throws ImageReadException, IOException { -646 final ImageContents imageContents = readFile(byteSource, false); -647 -648 if (imageContents == null) { -649 throw new ImageReadException("GIF: Couldn't read blocks"); -650 } -651 -652 final GifHeaderInfo ghi = imageContents.gifHeaderInfo; -653 if (ghi == null) { -654 throw new ImageReadException("GIF: Couldn't read Header"); -655 } -656 -657 final ImageDescriptor id = (ImageDescriptor) findBlock(imageContents.blocks, -658 IMAGE_SEPARATOR); -659 if (id == null) { -660 throw new ImageReadException("GIF: Couldn't read Image Descriptor"); -661 } -662 final GraphicControlExtension gce = (GraphicControlExtension) findBlock( -663 imageContents.blocks, GRAPHIC_CONTROL_EXTENSION); -664 -665 // Prefer the size information in the ImageDescriptor; it is more -666 // reliable -667 // than the size information in the header. -668 final int width = id.imageWidth; -669 final int height = id.imageHeight; -670 -671 boolean hasAlpha = false; -672 if (gce != null && gce.transparency) { -673 hasAlpha = true; -674 } -675 -676 final ImageBuilder imageBuilder = new ImageBuilder(width, height, hasAlpha); -677 -678 int[] colorTable; -679 if (id.localColorTable != null) { -680 colorTable = getColorTable(id.localColorTable); -681 } else if (imageContents.globalColorTable != null) { -682 colorTable = getColorTable(imageContents.globalColorTable); -683 } else { -684 throw new ImageReadException("Gif: No Color Table"); -685 } -686 -687 int transparentIndex = -1; -688 if (gce != null && hasAlpha) { -689 transparentIndex = gce.transparentColorIndex; -690 } -691 -692 int counter = 0; -693 -694 final int rowsInPass1 = (height + 7) / 8; -695 final int rowsInPass2 = (height + 3) / 8; -696 final int rowsInPass3 = (height + 1) / 4; -697 final int rowsInPass4 = (height) / 2; -698 -699 for (int row = 0; row < height; row++) { -700 int y; -701 if (id.interlaceFlag) { -702 int theRow = row; -703 if (theRow < rowsInPass1) { -704 y = theRow * 8; -705 } else { -706 theRow -= rowsInPass1; -707 if (theRow < (rowsInPass2)) { -708 y = 4 + (theRow * 8); -709 } else { -710 theRow -= rowsInPass2; -711 if (theRow < (rowsInPass3)) { -712 y = 2 + (theRow * 4); -713 } else { -714 theRow -= rowsInPass3; -715 if (theRow < (rowsInPass4)) { -716 y = 1 + (theRow * 2); -717 } else { -718 throw new ImageReadException("Gif: Strange Row"); -719 } -720 } -721 } -722 } -723 } else { -724 y = row; -725 } -726 -727 for (int x = 0; x < width; x++) { -728 final int index = 0xff & id.imageData[counter++]; -729 int rgb = colorTable[index]; -730 -731 if (transparentIndex == index) { -732 rgb = 0x00; -733 } -734 -735 imageBuilder.setRGB(x, y, rgb); -736 } -737 -738 } -739 -740 return imageBuilder.getBufferedImage(); -741 -742 } -743 -744 private void writeAsSubBlocks(final OutputStream os, final byte[] bytes) throws IOException { -745 int index = 0; -746 -747 while (index < bytes.length) { -748 final int blockSize = Math.min(bytes.length - index, 255); -749 os.write(blockSize); -750 os.write(bytes, index, blockSize); -751 index += blockSize; -752 } -753 os.write(0); // last block -754 } -755 -756 @Override -757 public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) -758 throws ImageWriteException, IOException { -759 // make copy of params; we'll clear keys as we consume them. -760 params = new HashMap<String, Object>(params); -761 -762 final boolean verbose = Boolean.TRUE.equals(params.get(PARAM_KEY_VERBOSE)); -763 -764 // clear format key. -765 if (params.containsKey(PARAM_KEY_FORMAT)) { -766 params.remove(PARAM_KEY_FORMAT); -767 } -768 if (params.containsKey(PARAM_KEY_VERBOSE)) { -769 params.remove(PARAM_KEY_VERBOSE); -770 } -771 -772 String xmpXml = null; -773 if (params.containsKey(PARAM_KEY_XMP_XML)) { -774 xmpXml = (String) params.get(PARAM_KEY_XMP_XML); -775 params.remove(PARAM_KEY_XMP_XML); -776 } -777 -778 if (!params.isEmpty()) { -779 final Object firstKey = params.keySet().iterator().next(); -780 throw new ImageWriteException("Unknown parameter: " + firstKey); -781 } -782 -783 final int width = src.getWidth(); -784 final int height = src.getHeight(); -785 -786 final boolean hasAlpha = new PaletteFactory().hasTransparency(src); -787 -788 final int maxColors = hasAlpha ? 255 : 256; -789 -790 Palette palette2 = new PaletteFactory().makeExactRgbPaletteSimple(src, maxColors); -791 // int palette[] = new PaletteFactory().makePaletteSimple(src, 256); -792 // Map palette_map = paletteToMap(palette); -793 -794 if (palette2 == null) { -795 palette2 = new PaletteFactory().makeQuantizedRgbPalette(src, maxColors); -796 if (verbose) { -797 System.out.println("quantizing"); -798 } -799 } else if (verbose) { -800 System.out.println("exact palette"); -801 } -802 -803 if (palette2 == null) { -804 throw new ImageWriteException("Gif: can't write images with more than 256 colors"); -805 } -806 final int paletteSize = palette2.length() + (hasAlpha ? 1 : 0); -807 -808 final BinaryOutputStream bos = new BinaryOutputStream(os, ByteOrder.LITTLE_ENDIAN); -809 -810 // write Header -811 os.write(0x47); // G magic numbers -812 os.write(0x49); // I -813 os.write(0x46); // F -814 -815 os.write(0x38); // 8 version magic numbers -816 os.write(0x39); // 9 -817 os.write(0x61); // a -818 -819 // Logical Screen Descriptor. -820 -821 bos.write2Bytes(width); -822 bos.write2Bytes(height); -823 -824 final int colorTableScaleLessOne = (paletteSize > 128) ? 7 -825 : (paletteSize > 64) ? 6 : (paletteSize > 32) ? 5 -826 : (paletteSize > 16) ? 4 : (paletteSize > 8) ? 3 -827 : (paletteSize > 4) ? 2 -828 : (paletteSize > 2) ? 1 : 0; -829 -830 final int colorTableSizeInFormat = 1 << (colorTableScaleLessOne + 1); -831 { -832 final byte colorResolution = (byte) colorTableScaleLessOne; // TODO: -833 -834 final boolean globalColorTableFlag = false; -835 final boolean sortFlag = false; -836 final int globalColorTableFlagMask = 1 << 7; -837 final int sortFlagMask = 8; -838 final int sizeOfGlobalColorTable = 0; -839 -840 final int packedFields = ((globalColorTableFlag ? globalColorTableFlagMask -841 : 0) -842 | (sortFlag ? sortFlagMask : 0) -843 | ((7 & colorResolution) << 4) | (7 & sizeOfGlobalColorTable)); -844 bos.write(packedFields); // one byte -845 } -846 { -847 final byte backgroundColorIndex = 0; -848 bos.write(backgroundColorIndex); -849 } -850 { -851 final byte pixelAspectRatio = 0; -852 bos.write(pixelAspectRatio); -853 } -854 -855 //{ -856 // write Global Color Table. -857 -858 //} -859 -860 { // ALWAYS write GraphicControlExtension -861 bos.write(EXTENSION_CODE); -862 bos.write((byte) 0xf9); -863 // bos.write(0xff & (kGraphicControlExtension >> 8)); -864 // bos.write(0xff & (kGraphicControlExtension >> 0)); -865 -866 bos.write((byte) 4); // block size; -867 final int packedFields = hasAlpha ? 1 : 0; // transparency flag -868 bos.write((byte) packedFields); -869 bos.write((byte) 0); // Delay Time +499 // FIXME should throw UOE +500 @Override +501 public ImageMetadata getMetadata(final ByteSource byteSource, final Map<String, Object> params) +502 throws ImageReadException, IOException { +503 return null; +504 } +505 +506 private List<String> getComments(final List<GifBlock> blocks) throws IOException { +507 final List<String> result = new ArrayList<String>(); +508 final int code = 0x21fe; +509 +510 for (GifBlock block : blocks) { +511 if (block.blockCode == code) { +512 final byte[] bytes = ((GenericGifBlock) block).appendSubBlocks(); +513 result.add(new String(bytes, "US-ASCII")); +514 } +515 } +516 +517 return result; +518 } +519 +520 @Override +521 public ImageInfo getImageInfo(final ByteSource byteSource, final Map<String, Object> params) +522 throws ImageReadException, IOException { +523 final ImageContents blocks = readFile(byteSource, false); +524 +525 if (blocks == null) { +526 throw new ImageReadException("GIF: Couldn't read blocks"); +527 } +528 +529 final GifHeaderInfo bhi = blocks.gifHeaderInfo; +530 if (bhi == null) { +531 throw new ImageReadException("GIF: Couldn't read Header"); +532 } +533 +534 final ImageDescriptor id = (ImageDescriptor) findBlock(blocks.blocks, +535 IMAGE_SEPARATOR); +536 if (id == null) { +537 throw new ImageReadException("GIF: Couldn't read ImageDescriptor"); +538 } +539 +540 final GraphicControlExtension gce = (GraphicControlExtension) findBlock( +541 blocks.blocks, GRAPHIC_CONTROL_EXTENSION); +542 +543 // Prefer the size information in the ImageDescriptor; it is more +544 // reliable than the size information in the header. +545 final int height = id.imageHeight; +546 final int width = id.imageWidth; +547 +548 final List<String> comments = getComments(blocks.blocks); +549 final int bitsPerPixel = (bhi.colorResolution + 1); +550 final ImageFormat format = ImageFormats.GIF; +551 final String formatName = "GIF Graphics Interchange Format"; +552 final String mimeType = "image/gif"; +553 // we ought to count images, but don't yet. +554 final int numberOfImages = -1; +555 +556 final boolean progressive = id.interlaceFlag; +557 +558 final int physicalWidthDpi = 72; +559 final float physicalWidthInch = (float) ((double) width / (double) physicalWidthDpi); +560 final int physicalHeightDpi = 72; +561 final float physicalHeightInch = (float) ((double) height / (double) physicalHeightDpi); +562 +563 final String formatDetails = "Gif " + ((char) blocks.gifHeaderInfo.version1) +564 + ((char) blocks.gifHeaderInfo.version2) +565 + ((char) blocks.gifHeaderInfo.version3); +566 +567 boolean transparent = false; +568 if (gce != null && gce.transparency) { +569 transparent = true; +570 } +571 +572 final boolean usesPalette = true; +573 final ImageInfo.ColorType colorType = ImageInfo.ColorType.RGB; +574 final ImageInfo.CompressionAlgorithm compressionAlgorithm = ImageInfo.CompressionAlgorithm.LZW; +575 +576 return new ImageInfo(formatDetails, bitsPerPixel, comments, +577 format, formatName, height, mimeType, numberOfImages, +578 physicalHeightDpi, physicalHeightInch, physicalWidthDpi, +579 physicalWidthInch, width, progressive, transparent, +580 usesPalette, colorType, compressionAlgorithm); +581 } +582 +583 @Override +584 public boolean dumpImageFile(final PrintWriter pw, final ByteSource byteSource) +585 throws ImageReadException, IOException { +586 pw.println("gif.dumpImageFile"); +587 +588 final ImageInfo imageData = getImageInfo(byteSource); +589 if (imageData == null) { +590 return false; +591 } +592 +593 imageData.toString(pw, ""); +594 +595 final ImageContents blocks = readFile(byteSource, false); +596 +597 pw.println("gif.blocks: " + blocks.blocks.size()); +598 for (int i = 0; i < blocks.blocks.size(); i++) { +599 final GifBlock gifBlock = blocks.blocks.get(i); +600 this.debugNumber(pw, "\t" + i + " (" +601 + gifBlock.getClass().getName() + ")", +602 gifBlock.blockCode, 4); +603 } +604 +605 pw.println(""); +606 +607 return true; +608 } +609 +610 private int[] getColorTable(final byte[] bytes) throws ImageReadException { +611 if ((bytes.length % 3) != 0) { +612 throw new ImageReadException("Bad Color Table Length: " +613 + bytes.length); +614 } +615 final int length = bytes.length / 3; +616 +617 final int[] result = new int[length]; +618 +619 for (int i = 0; i < length; i++) { +620 final int red = 0xff & bytes[(i * 3) + 0]; +621 final int green = 0xff & bytes[(i * 3) + 1]; +622 final int blue = 0xff & bytes[(i * 3) + 2]; +623 +624 final int alpha = 0xff; +625 +626 final int rgb = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0); +627 result[i] = rgb; +628 } +629 +630 return result; +631 } +632 +633 @Override +634 public FormatCompliance getFormatCompliance(final ByteSource byteSource) +635 throws ImageReadException, IOException { +636 final FormatCompliance result = new FormatCompliance( +637 byteSource.getDescription()); +638 +639 readFile(byteSource, false, result); +640 +641 return result; +642 } +643 +644 @Override +645 public BufferedImage getBufferedImage(final ByteSource byteSource, final Map<String, Object> params) +646 throws ImageReadException, IOException { +647 final ImageContents imageContents = readFile(byteSource, false); +648 +649 if (imageContents == null) { +650 throw new ImageReadException("GIF: Couldn't read blocks"); +651 } +652 +653 final GifHeaderInfo ghi = imageContents.gifHeaderInfo; +654 if (ghi == null) { +655 throw new ImageReadException("GIF: Couldn't read Header"); +656 } +657 +658 final ImageDescriptor id = (ImageDescriptor) findBlock(imageContents.blocks, +659 IMAGE_SEPARATOR); +660 if (id == null) { +661 throw new ImageReadException("GIF: Couldn't read Image Descriptor"); +662 } +663 final GraphicControlExtension gce = (GraphicControlExtension) findBlock( +664 imageContents.blocks, GRAPHIC_CONTROL_EXTENSION); +665 +666 // Prefer the size information in the ImageDescriptor; it is more +667 // reliable +668 // than the size information in the header. +669 final int width = id.imageWidth; +670 final int height = id.imageHeight; +671 +672 boolean hasAlpha = false; +673 if (gce != null && gce.transparency) { +674 hasAlpha = true; +675 } +676 +677 final ImageBuilder imageBuilder = new ImageBuilder(width, height, hasAlpha); +678 +679 int[] colorTable; +680 if (id.localColorTable != null) { +681 colorTable = getColorTable(id.localColorTable); +682 } else if (imageContents.globalColorTable != null) { +683 colorTable = getColorTable(imageContents.globalColorTable); +684 } else { +685 throw new ImageReadException("Gif: No Color Table"); +686 } +687 +688 int transparentIndex = -1; +689 if (gce != null && hasAlpha) { +690 transparentIndex = gce.transparentColorIndex; +691 } +692 +693 int counter = 0; +694 +695 final int rowsInPass1 = (height + 7) / 8; +696 final int rowsInPass2 = (height + 3) / 8; +697 final int rowsInPass3 = (height + 1) / 4; +698 final int rowsInPass4 = (height) / 2; +699 +700 for (int row = 0; row < height; row++) { +701 int y; +702 if (id.interlaceFlag) { +703 int theRow = row; +704 if (theRow < rowsInPass1) { +705 y = theRow * 8; +706 } else { +707 theRow -= rowsInPass1; +708 if (theRow < (rowsInPass2)) { +709 y = 4 + (theRow * 8); +710 } else { +711 theRow -= rowsInPass2; +712 if (theRow < (rowsInPass3)) { +713 y = 2 + (theRow * 4); +714 } else { +715 theRow -= rowsInPass3; +716 if (theRow < (rowsInPass4)) { +717 y = 1 + (theRow * 2); +718 } else { +719 throw new ImageReadException("Gif: Strange Row"); +720 } +721 } +722 } +723 } +724 } else { +725 y = row; +726 } +727 +728 for (int x = 0; x < width; x++) { +729 final int index = 0xff & id.imageData[counter++]; +730 int rgb = colorTable[index]; +731 +732 if (transparentIndex == index) { +733 rgb = 0x00; +734 } +735 +736 imageBuilder.setRGB(x, y, rgb); +737 } +738 +739 } +740 +741 return imageBuilder.getBufferedImage(); +742 +743 } +744 +745 private void writeAsSubBlocks(final OutputStream os, final byte[] bytes) throws IOException { +746 int index = 0; +747 +748 while (index < bytes.length) { +749 final int blockSize = Math.min(bytes.length - index, 255); +750 os.write(blockSize); +751 os.write(bytes, index, blockSize); +752 index += blockSize; +753 } +754 os.write(0); // last block +755 } +756 +757 @Override +758 public void writeImage(final BufferedImage src, final OutputStream os, Map<String, Object> params) +759 throws ImageWriteException, IOException { +760 // make copy of params; we'll clear keys as we consume them. +761 params = new HashMap<String, Object>(params); +762 +763 final boolean verbose = Boolean.TRUE.equals(params.get(PARAM_KEY_VERBOSE)); +764 +765 // clear format key. +766 if (params.containsKey(PARAM_KEY_FORMAT)) { [... 555 lines stripped ...]