You are viewing a plain text version of this content. The canonical link for it is here.
Posted to sanselan-commits@incubator.apache.org by cm...@apache.org on 2008/07/15 22:31:25 UTC
svn commit: r677073 [1/2] - in /incubator/sanselan/trunk/src:
main/java/org/apache/sanselan/common/
main/java/org/apache/sanselan/formats/gif/
main/java/org/apache/sanselan/formats/png/
main/java/org/apache/sanselan/formats/png/chunks/ test/data/images...
Author: cmchen
Date: Tue Jul 15 15:31:25 2008
New Revision: 677073
URL: http://svn.apache.org/viewvc?rev=677073&view=rev
Log:
jira issue: SANSELAN-5
Fixed two issues in the PNG reader. Wasn't handling the 16-bit mode 4 PNGs properly. Also, wasn't gamma-correcting non-palette values properly in PNGs.
Added very helpful pngs (and variants) to the test suite and added a unit test around png->gif conversion.
Also, took the opportunity to remove some debuging statements and dead code.
Added:
incubator/sanselan/trunk/src/test/data/images/png/2/
incubator/sanselan/trunk/src/test/data/images/png/2/12118.png (with props)
incubator/sanselan/trunk/src/test/data/images/png/2/28569-4.png (with props)
incubator/sanselan/trunk/src/test/data/images/png/2/28569-8.png (with props)
incubator/sanselan/trunk/src/test/data/images/png/2/28569.png (with props)
incubator/sanselan/trunk/src/test/data/images/png/2/info.txt (with props)
incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/png/ConvertPngToGifTest.java (with props)
incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/png/PngBaseTest.java (with props)
Modified:
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/ScanExpediter.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/ScanExpediterInterlaced.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/ScanExpediterSimple.java
incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/chunks/PNGChunkPLTE.java
incubator/sanselan/trunk/src/test/java/org/apache/sanselan/SanselanTest.java
incubator/sanselan/trunk/src/test/java/org/apache/sanselan/formats/png/PngReadTest.java
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/common/BinaryFileParser.java Tue Jul 15 15:31:25 2008
@@ -63,6 +63,11 @@
return byteOrder;
}
+ protected final int convertByteArrayToInt(String name, int start, byte bytes[])
+ {
+ return convertByteArrayToInt(name, bytes, start, byteOrder);
+ }
+
protected final int convertByteArrayToInt(String name, byte bytes[])
{
return convertByteArrayToInt(name, bytes, byteOrder);
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/gif/GifImageParser.java Tue Jul 15 15:31:25 2008
@@ -43,51 +43,40 @@
import org.apache.sanselan.palette.Palette;
import org.apache.sanselan.palette.PaletteFactory;
import org.apache.sanselan.util.Debug;
+import org.apache.sanselan.util.ParamMap;
-public class GifImageParser extends ImageParser
-{
+public class GifImageParser extends ImageParser {
- public GifImageParser()
- {
+ public GifImageParser() {
super.setByteOrder(BYTE_ORDER_LSB);
}
- public String getName()
- {
+ public String getName() {
return "Gif-Custom";
}
- public String getDefaultExtension()
- {
+ public String getDefaultExtension() {
return DEFAULT_EXTENSION;
}
private static final String DEFAULT_EXTENSION = ".gif";
- private static final String ACCEPTED_EXTENSIONS[] = {
- DEFAULT_EXTENSION,
- };
+ private static final String ACCEPTED_EXTENSIONS[] = { DEFAULT_EXTENSION, };
- protected String[] getAcceptedExtensions()
- {
+ protected String[] getAcceptedExtensions() {
return ACCEPTED_EXTENSIONS;
}
- protected ImageFormat[] getAcceptedTypes()
- {
- return new ImageFormat[]{
- ImageFormat.IMAGE_FORMAT_GIF, //
+ protected ImageFormat[] getAcceptedTypes() {
+ return new ImageFormat[] { ImageFormat.IMAGE_FORMAT_GIF, //
};
}
- private static final byte GIF_HEADER_SIGNATURE[] = {
- 71, 73, 70
- };
+ private static final byte GIF_HEADER_SIGNATURE[] = { 71, 73, 70 };
private GIFHeaderInfo readHeader(InputStream is,
FormatCompliance formatCompliance) throws ImageReadException,
- IOException
- {
+ IOException {
byte identifier1 = readByte("identifier1", is, "Not a Valid GIF File");
byte identifier2 = readByte("identifier2", is, "Not a Valid GIF File");
byte identifier3 = readByte("identifier3", is, "Not a Valid GIF File");
@@ -96,16 +85,12 @@
byte version2 = readByte("version2", is, "Not a Valid GIF File");
byte version3 = readByte("version3", is, "Not a Valid GIF File");
- if (formatCompliance != null)
- {
+ if (formatCompliance != null) {
formatCompliance.compare_bytes("Signature", GIF_HEADER_SIGNATURE,
- new byte[]{
- identifier1, identifier2, identifier3,
- });
+ new byte[] { identifier1, identifier2, identifier3, });
formatCompliance.compare("version", 56, version1);
- formatCompliance.compare("version", new int[]{
- 55, 57,
- }, version2);
+ formatCompliance
+ .compare("version", new int[] { 55, 57, }, version2);
formatCompliance.compare("version", 97, version3);
}
@@ -121,8 +106,7 @@
int logicalScreenHeight = read2Bytes("Logical Screen Height", is,
"Not a Valid GIF File");
- if (formatCompliance != null)
- {
+ if (formatCompliance != null) {
formatCompliance.checkBounds("Width", 1, Integer.MAX_VALUE,
logicalScreenWidth);
formatCompliance.checkBounds("Height", 1, Integer.MAX_VALUE,
@@ -153,8 +137,7 @@
System.out.println("SizeofGlobalColorTable: "
+ sizeofGlobalColorTable);
- if (formatCompliance != null)
- {
+ if (formatCompliance != null) {
if (globalColorTableFlag && backgroundColorIndex != -1)
formatCompliance.checkBounds("Background Color Index", 0,
convertColorTableSize(sizeofGlobalColorTable),
@@ -169,8 +152,7 @@
}
private GraphicControlExtension readGraphicControlExtension(int code,
- InputStream is) throws ImageReadException, IOException
- {
+ InputStream is) throws ImageReadException, IOException {
readByte("block_size", is, "GIF: corrupt GraphicControlExt");
int packed = readByte("packed fields", is,
"GIF: corrupt GraphicControlExt");
@@ -189,8 +171,7 @@
}
private byte[] readSubBlock(InputStream is) throws ImageReadException,
- IOException
- {
+ IOException {
int block_size = 0xff & readByte("block_size", is, "GIF: corrupt block");
byte bytes[] = readByteArray("block", block_size, is,
@@ -200,22 +181,19 @@
}
protected GenericGIFBlock readGenericGIFBlock(InputStream is, int code)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
return readGenericGIFBlock(is, code, null);
}
protected GenericGIFBlock readGenericGIFBlock(InputStream is, int code,
- byte first[]) throws ImageReadException, IOException
- {
+ byte first[]) throws ImageReadException, IOException {
byte bytes[] = null;
ArrayList subblocks = new ArrayList();
if (first != null)
subblocks.add(first);
- while (true)
- {
+ while (true) {
bytes = readSubBlock(is);
if (bytes.length < 1)
break;
@@ -233,105 +211,100 @@
private ArrayList readBlocks(GIFHeaderInfo ghi, InputStream is,
boolean stop_before_image_data, FormatCompliance formatCompliance)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
ArrayList result = new ArrayList();
- while (true)
- {
+ while (true) {
int code = is.read();
- // this.debugNumber("code: ", code);
+ // this.debugNumber("code: ", code);
- switch (code)
- {
- case -1 :
- throw new ImageReadException("GIF: unexpected end of data");
+ switch (code) {
+ case -1:
+ throw new ImageReadException("GIF: unexpected end of data");
+
+ case IMAGE_SEPARATOR:
+ ImageDescriptor id = readImageDescriptor(ghi, code, is,
+ stop_before_image_data, formatCompliance);
+ result.add(id);
- case IMAGE_SEPARATOR :
- ImageDescriptor id = readImageDescriptor(ghi, code, is,
- stop_before_image_data, formatCompliance);
- result.add(id);
+ break;
+ case 0x21: // extension
+ {
+ int extension_code = is.read();
+ // this.debugNumber("extension_code: ", extension_code);
+ int complete_code = ((0xff & code) << 8)
+ | (0xff & extension_code);
+
+ switch (extension_code) {
+ case 0xf9:
+ GraphicControlExtension gce = readGraphicControlExtension(
+ complete_code, is);
+ result.add(gce);
break;
- case 0x21 : // extension
- {
- int extension_code = is.read();
- // this.debugNumber("extension_code: ", extension_code);
- int complete_code = ((0xff & code) << 8)
- | (0xff & extension_code);
-
- switch (extension_code)
- {
- case 0xf9 :
- GraphicControlExtension gce = readGraphicControlExtension(
- complete_code, is);
- result.add(gce);
- break;
-
- case COMMENT_EXTENSION : {
- GenericGIFBlock block = readGenericGIFBlock(is,
- complete_code);
- result.add(block);
- break;
- }
+ case COMMENT_EXTENSION: {
+ GenericGIFBlock block = readGenericGIFBlock(is,
+ complete_code);
+ result.add(block);
+ break;
+ }
- case PLAIN_TEXT_EXTENSION : {
- GenericGIFBlock block = readGenericGIFBlock(is,
- complete_code);
- result.add(block);
- break;
- }
+ case PLAIN_TEXT_EXTENSION: {
+ GenericGIFBlock block = readGenericGIFBlock(is,
+ complete_code);
+ result.add(block);
+ break;
+ }
- case 0xff : // 255 (hex 0xFF) Application Extension Label
- {
- byte label[] = readSubBlock(is);
-
- if (formatCompliance != null)
- formatCompliance.addComment(
- "Unknown Application Extension ("
- + new String(label) + ")",
- complete_code);
-
- // if (label == new String("ICCRGBG1"))
- {
- // GIF's can have embedded ICC Profiles - who knew?
- }
+ case 0xff: // 255 (hex 0xFF) Application Extension Label
+ {
+ byte label[] = readSubBlock(is);
- if ((label != null) && (label.length > 0))
- {
- GenericGIFBlock block = readGenericGIFBlock(is,
- complete_code, label);
- byte bytes[] = block.appendSubBlocks();
+ if (formatCompliance != null)
+ formatCompliance.addComment(
+ "Unknown Application Extension ("
+ + new String(label) + ")",
+ complete_code);
- result.add(block);
- }
- break;
- }
+ // if (label == new String("ICCRGBG1"))
+ {
+ // GIF's can have embedded ICC Profiles - who knew?
+ }
- default : {
+ if ((label != null) && (label.length > 0)) {
+ GenericGIFBlock block = readGenericGIFBlock(is,
+ complete_code, label);
+ byte bytes[] = block.appendSubBlocks();
- if (formatCompliance != null)
- formatCompliance.addComment("Unknown block",
- complete_code);
-
- GenericGIFBlock block = readGenericGIFBlock(is,
- complete_code);
- result.add(block);
- break;
- }
+ result.add(block);
}
- }
break;
+ }
- case TERMINATOR_BYTE :
- return result;
+ default: {
- case 0x00 : // bad byte, but keep going and see what happens
+ if (formatCompliance != null)
+ formatCompliance.addComment("Unknown block",
+ complete_code);
+
+ GenericGIFBlock block = readGenericGIFBlock(is,
+ complete_code);
+ result.add(block);
break;
+ }
+ }
+ }
+ break;
+
+ case TERMINATOR_BYTE:
+ return result;
+
+ case 0x00: // bad byte, but keep going and see what happens
+ break;
- default :
- throw new ImageReadException("GIF: unknown code: " + code);
+ default:
+ throw new ImageReadException("GIF: unknown code: " + code);
}
}
}
@@ -339,8 +312,7 @@
private ImageDescriptor readImageDescriptor(GIFHeaderInfo ghi,
int blockCode, InputStream is, boolean stop_before_image_data,
FormatCompliance formatCompliance) throws ImageReadException,
- IOException
- {
+ IOException {
int ImageLeftPosition = read2Bytes("Image Left Position", is,
"Not a Valid GIF File");
int ImageTopPosition = read2Bytes("Image Top Position", is,
@@ -350,8 +322,7 @@
byte PackedFields = readByte("Packed Fields", is,
"Not a Valid GIF File");
- if (formatCompliance != null)
- {
+ if (formatCompliance != null) {
formatCompliance.checkBounds("Width", 1, ghi.logicalScreenWidth,
imageWidth);
formatCompliance.checkBounds("Height", 1, ghi.logicalScreenHeight,
@@ -386,8 +357,7 @@
formatCompliance);
byte imageData[] = null;
- if (!stop_before_image_data)
- {
+ if (!stop_before_image_data) {
int LZWMinimumCodeSize = is.read();
GenericGIFBlock block = readGenericGIFBlock(is, -1);
@@ -398,9 +368,7 @@
MyLZWDecompressor myLzwDecompressor = new MyLZWDecompressor(
LZWMinimumCodeSize, BYTE_ORDER_LSB);
imageData = myLzwDecompressor.decompress(bais, size);
- }
- else
- {
+ } else {
int LZWMinimumCodeSize = is.read();
if (debug)
System.out.println("LZWMinimumCodeSize: " + LZWMinimumCodeSize);
@@ -416,8 +384,7 @@
return result;
}
- private int simple_pow(int base, int power)
- {
+ private int simple_pow(int base, int power) {
int result = 1;
for (int i = 0; i < power; i++)
@@ -426,15 +393,13 @@
return result;
}
- private int convertColorTableSize(int ct_size)
- {
+ private int convertColorTableSize(int ct_size) {
return 3 * simple_pow(2, ct_size + 1);
}
private byte[] readColorTable(InputStream is, int ct_size,
FormatCompliance formatCompliance) throws ImageReadException,
- IOException
- {
+ IOException {
int actual_size = convertColorTableSize(ct_size);
byte bytes[] = readByteArray("block", actual_size, is,
@@ -444,33 +409,24 @@
}
private GIFHeaderInfo readHeader(ByteSource byteSource)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
InputStream is = null;
- try
- {
+ try {
is = byteSource.getInputStream();
return readHeader(is, FormatCompliance.getDefault());
- }
- finally
- {
- try
- {
+ } finally {
+ try {
is.close();
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
Debug.debug(e);
}
}
}
- private GIFBlock findBlock(ArrayList v, int code)
- {
- for (int i = 0; i < v.size(); i++)
- {
+ private GIFBlock findBlock(ArrayList v, int code) {
+ for (int i = 0; i < v.size(); i++) {
GIFBlock fGIFBlock = (GIFBlock) v.get(i);
if (fGIFBlock.blockCode == code)
return fGIFBlock;
@@ -480,19 +436,16 @@
private ImageContents readFile(ByteSource byteSource,
boolean stop_before_image_data) throws ImageReadException,
- IOException
- {
+ IOException {
return readFile(byteSource, stop_before_image_data, FormatCompliance
.getDefault());
}
private ImageContents readFile(ByteSource byteSource,
boolean stop_before_image_data, FormatCompliance formatCompliance)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
InputStream is = null;
- try
- {
+ try {
is = byteSource.getInputStream();
GIFHeaderInfo ghi = readHeader(is, formatCompliance);
@@ -509,16 +462,11 @@
blocks);
return result;
- }
- finally
- {
- try
- {
- // bis.close();
+ } finally {
+ try {
+ // bis.close();
is.close();
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
Debug.debug(e);
}
@@ -526,15 +474,12 @@
}
public byte[] getICCProfileBytes(ByteSource byteSource, Map params)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
return null;
}
- public Dimension getImageSize(ByteSource byteSource,
- Map params)
- throws ImageReadException, IOException
- {
+ public Dimension getImageSize(ByteSource byteSource, Map params)
+ throws ImageReadException, IOException {
GIFHeaderInfo bhi = readHeader(byteSource);
if (bhi == null)
@@ -544,33 +489,27 @@
}
- public byte[] embedICCProfile(byte image[], byte profile[])
- {
+ public byte[] embedICCProfile(byte image[], byte profile[]) {
return null;
}
- public boolean embedICCProfile(File src, File dst, byte profile[])
- {
+ public boolean embedICCProfile(File src, File dst, byte profile[]) {
return false;
}
public IImageMetadata getMetadata(ByteSource byteSource, Map params)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
return null;
}
private ArrayList getComments(ArrayList v) throws ImageReadException,
- IOException
- {
+ IOException {
ArrayList result = new ArrayList();
int code = 0x21fe;
- for (int i = 0; i < v.size(); i++)
- {
+ for (int i = 0; i < v.size(); i++) {
GIFBlock block = (GIFBlock) v.get(i);
- if (block.blockCode == code)
- {
+ if (block.blockCode == code) {
byte bytes[] = ((GenericGIFBlock) block).appendSubBlocks();
result.add(new String(bytes));
}
@@ -580,8 +519,7 @@
}
public ImageInfo getImageInfo(ByteSource byteSource, Map params)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
ImageContents blocks = readFile(byteSource, false);
if (blocks == null)
@@ -625,8 +563,7 @@
+ ((char) blocks.gifHeaderInfo.version3);
boolean isTransparent = false;
- if (gce != null)
- {
+ if (gce != null) {
if (gce.transparency)
isTransparent = true;
}
@@ -645,8 +582,7 @@
}
public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
pw.println("gif.dumpImageFile");
{
@@ -663,8 +599,7 @@
return false;
pw.println("gif.blocks: " + blocks.blocks.size());
- for (int i = 0; i < blocks.blocks.size(); i++)
- {
+ for (int i = 0; i < blocks.blocks.size(); i++) {
GIFBlock fGIFBlock = (GIFBlock) blocks.blocks.get(i);
this.debugNumber(pw, "\t" + i + " ("
+ fGIFBlock.getClass().getName() + ")",
@@ -679,8 +614,7 @@
}
private int[] getColorTable(byte bytes[]) throws ImageReadException,
- IOException
- {
+ IOException {
if ((bytes.length % 3) != 0)
throw new ImageReadException("Bad Color Table Length: "
+ bytes.length);
@@ -688,8 +622,7 @@
int result[] = new int[length];
- for (int i = 0; i < length; i++)
- {
+ for (int i = 0; i < length; i++) {
int red = 0xff & bytes[(i * 3) + 0];
int green = 0xff & bytes[(i * 3) + 1];
int blue = 0xff & bytes[(i * 3) + 2];
@@ -704,8 +637,7 @@
}
public FormatCompliance getFormatCompliance(ByteSource byteSource)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
FormatCompliance result = new FormatCompliance(byteSource
.getDescription());
@@ -715,8 +647,7 @@
}
public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
- throws ImageReadException, IOException
- {
+ throws ImageReadException, IOException {
ImageContents imageContents = readFile(byteSource, false);
if (imageContents == null)
@@ -753,11 +684,12 @@
if (gce.transparency)
transparentIndex = gce.transparentColorIndex;
- // Debug.debug("charles TransparentIndex", TransparentIndex);
+ // Debug.debug("charles TransparentIndex", TransparentIndex);
int counter = 0;
- // ByteArrayInputStream bais = new ByteArrayInputStream(id.ImageData);
- // for (int y = 0; y < height; y++)
+ // ByteArrayInputStream bais = new
+ // ByteArrayInputStream(id.ImageData);
+ // for (int y = 0; y < height; y++)
int rows_in_pass_1 = (height + 7) / 8;
int rows_in_pass_2 = (height + 3) / 8;
@@ -766,27 +698,22 @@
DataBuffer db = result.getRaster().getDataBuffer();
- for (int row = 0; row < height; row++)
- {
+ for (int row = 0; row < height; row++) {
int y;
- if (id.interlaceFlag)
- {
+ if (id.interlaceFlag) {
int the_row = row;
if (the_row < rows_in_pass_1)
y = the_row * 8;
- else
- {
+ else {
the_row -= rows_in_pass_1;
if (the_row < (rows_in_pass_2))
y = 4 + (the_row * 8);
- else
- {
+ else {
the_row -= rows_in_pass_2;
if (the_row < (rows_in_pass_3))
y = 2 + (the_row * 4);
- else
- {
+ else {
the_row -= rows_in_pass_3;
if (the_row < (rows_in_pass_4))
y = 1 + (the_row * 2);
@@ -796,13 +723,11 @@
}
}
}
- // System.out.println("row(" + row + "): " + y);
- }
- else
+ // System.out.println("row(" + row + "): " + y);
+ } else
y = row;
- for (int x = 0; x < width; x++)
- {
+ for (int x = 0; x < width; x++) {
int index = 0xff & id.imageData[counter++];
int rgb = colortable[index];
@@ -821,12 +746,10 @@
}
private void writeAsSubBlocks(OutputStream os, byte bytes[])
- throws IOException
- {
+ throws IOException {
int index = 0;
- while (index < bytes.length)
- {
+ while (index < bytes.length) {
int block_size = Math.min(bytes.length - index, 255);
os.write(block_size);
os.write(bytes, index, block_size);
@@ -840,17 +763,20 @@
private static final int SORT_FLAG_MASK = 1 << 5;
public void writeImage(BufferedImage src, OutputStream os, Map params)
- throws ImageWriteException, IOException
- {
+ throws ImageWriteException, IOException {
// make copy of params; we'll clear keys as we consume them.
params = new HashMap(params);
+ boolean verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
+ false);
+
// clear format key.
if (params.containsKey(PARAM_KEY_FORMAT))
params.remove(PARAM_KEY_FORMAT);
+ if (params.containsKey(PARAM_KEY_VERBOSE))
+ params.remove(PARAM_KEY_VERBOSE);
- if (params.size() > 0)
- {
+ if (params.size() > 0) {
Object firstKey = params.keySet().iterator().next();
throw new ImageWriteException("Unknown parameter: " + firstKey);
}
@@ -864,16 +790,15 @@
Palette palette2 = new PaletteFactory().makePaletteSimple(src,
max_colors);
- // int palette[] = new PaletteFactory().makePaletteSimple(src, 256);
- // Map palette_map = paletteToMap(palette);
+ // int palette[] = new PaletteFactory().makePaletteSimple(src, 256);
+ // Map palette_map = paletteToMap(palette);
- if (palette2 == null)
- {
+ if (palette2 == null) {
palette2 = new PaletteFactory().makePaletteQuantized(src,
max_colors);
- System.out.println("quantizing");
- }
- else
+ if (verbose)
+ System.out.println("quantizing");
+ } else if (verbose)
System.out.println("exact palette");
if (palette2 == null)
@@ -898,14 +823,10 @@
bos.write2Bytes(width);
bos.write2Bytes(height);
- int colorTableScaleLessOne = (palette_size > 128)
- ? 7
- : (palette_size > 64) ? 6 : (palette_size > 32)
- ? 5
- : (palette_size > 16) ? 4 : (palette_size > 8)
- ? 3
- : (palette_size > 4)
- ? 2
+ int colorTableScaleLessOne = (palette_size > 128) ? 7
+ : (palette_size > 64) ? 6 : (palette_size > 32) ? 5
+ : (palette_size > 16) ? 4 : (palette_size > 8) ? 3
+ : (palette_size > 4) ? 2
: (palette_size > 2) ? 1 : 0;
int colorTableSizeInFormat = 1 << (colorTableScaleLessOne + 1);
@@ -919,8 +840,7 @@
int sortFlagMask = 8;
int sizeOfGlobalColorTable = 0;
- int packedFields = ((globalColorTableFlag
- ? globalColorTableFlagMask
+ int packedFields = ((globalColorTableFlag ? globalColorTableFlagMask
: 0)
| (sortFlag ? sortFlagMask : 0)
| ((7 & colorResolution) << 4) | (7 & sizeOfGlobalColorTable));
@@ -939,40 +859,40 @@
}
- if (hasAlpha)
- { // write GraphicControlExtension
+ if (hasAlpha) { // write GraphicControlExtension
bos.write((byte) 0x21);
bos.write((byte) 0xf9);
- // bos.write(0xff & (kGraphicControlExtension >> 8));
- // bos.write(0xff & (kGraphicControlExtension >> 0));
+ // bos.write(0xff & (kGraphicControlExtension >> 8));
+ // bos.write(0xff & (kGraphicControlExtension >> 0));
bos.write((byte) 4); // block size;
int fPackedFields = hasAlpha ? 1 : 0; // transparency flag
bos.write((byte) fPackedFields);
- bos.write((byte) 0); // Delay Time
- bos.write((byte) 0); // Delay Time
- bos.write((byte) (hasAlpha ? palette2.length() : 0)); // Transparent Color Index
+ bos.write((byte) 0); // Delay Time
+ bos.write((byte) 0); // Delay Time
+ bos.write((byte) (hasAlpha ? palette2.length() : 0)); // Transparent
+ // Color
+ // Index
bos.write((byte) 0); // terminator
}
- { // Image Descriptor.
+ { // Image Descriptor.
bos.write(IMAGE_SEPARATOR);
bos.write2Bytes(0); // Image Left Position
- bos.write2Bytes(0); // Image Top Position
+ bos.write2Bytes(0); // Image Top Position
bos.write2Bytes(width); // Image Width
- bos.write2Bytes(height); // Image Height
+ bos.write2Bytes(height); // Image Height
{
boolean LocalColorTableFlag = true;
- // boolean LocalColorTableFlag = false;
+ // boolean LocalColorTableFlag = false;
boolean InterlaceFlag = false;
boolean SortFlag = false;
int SizeOfLocalColorTable = colorTableScaleLessOne;
- // int SizeOfLocalColorTable = 0;
+ // int SizeOfLocalColorTable = 0;
- int PackedFields = ((LocalColorTableFlag
- ? LOCAL_COLOR_TABLE_FLAG_MASK
+ int PackedFields = ((LocalColorTableFlag ? LOCAL_COLOR_TABLE_FLAG_MASK
: 0)
| (InterlaceFlag ? INTERLACE_FLAG_MASK : 0)
| (SortFlag ? SORT_FLAG_MASK : 0) | (7 & SizeOfLocalColorTable));
@@ -981,10 +901,8 @@
}
{ // write Local Color Table.
- for (int i = 0; i < colorTableSizeInFormat; i++)
- {
- if (i < palette2.length())
- {
+ for (int i = 0; i < colorTableSizeInFormat; i++) {
+ if (i < palette2.length()) {
int rgb = palette2.getEntry(i);
int red = 0xff & (rgb >> 16);
@@ -994,9 +912,7 @@
bos.write(red);
bos.write(green);
bos.write(blue);
- }
- else
- {
+ } else {
bos.write(0);
bos.write(0);
bos.write(0);
@@ -1007,32 +923,32 @@
{ // get Image Data.
int image_data_total = 0;
- int LZWMinimumCodeSize = colorTableScaleLessOne + 1; // TODO: make better choice here.
+ int LZWMinimumCodeSize = colorTableScaleLessOne + 1; // TODO:
+ // make
+ // better
+ // choice
+ // here.
bos.write(LZWMinimumCodeSize);
MyLZWCompressor compressor = new MyLZWCompressor(
- LZWMinimumCodeSize, BYTE_ORDER_LSB, false); // GIF Mode);
+ LZWMinimumCodeSize, BYTE_ORDER_LSB, false); // GIF
+ // Mode);
byte imagedata[] = new byte[width * height];
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
int argb = src.getRGB(x, y);
int rgb = 0xffffff & argb;
int index;
- if (hasAlpha)
- {
+ if (hasAlpha) {
int alpha = 0xff & (argb >> 24);
final int alphaThreshold = 255;
if (alpha < alphaThreshold)
index = palette2.length(); // is transparent
else
index = palette2.getPaletteIndex(rgb);
- }
- else
- {
+ } else {
index = palette2.getPaletteIndex(rgb);
}
@@ -1045,7 +961,7 @@
image_data_total += compressed.length;
}
- palette2.dump();
+// palette2.dump();
bos.write(TERMINATOR_BYTE);
}
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/BitParser.java Tue Jul 15 15:31:25 2008
@@ -19,70 +19,57 @@
import java.io.IOException;
import org.apache.sanselan.ImageReadException;
+import org.apache.sanselan.util.Debug;
public class BitParser
{
private final byte bytes[];
- private final int BitsPerPixel;
- private final int BitDepth;
+ private final int bitsPerPixel;
+ private final int bitDepth;
- public BitParser(byte bytes[], int BitsPerPixel, int BitDepth)
+ public BitParser(byte bytes[], int bitsPerPixel, int bitDepth)
{
this.bytes = bytes;
- this.BitsPerPixel = BitsPerPixel;
- this.BitDepth = BitDepth;
+ this.bitsPerPixel = bitsPerPixel;
+ this.bitDepth = bitDepth;
}
- public int getSample(int pixel_index_in_scanline, int SampleIndex)
+ public int getSample(int pixelIndexInScanline, int sampleIndex)
throws ImageReadException, IOException
{
- int pixel_index_bits = BitsPerPixel * pixel_index_in_scanline;
- int sample_index_bits = pixel_index_bits + (SampleIndex * BitDepth);
- // int sample_index_bytes = sample_index_bits / 8;
- int sample_index_bytes = sample_index_bits >> 3;
- // int sample_index_bytes = pixel_index_bits / 8;
-
- // System.out.println("sample_index_bytes: " + sample_index_bytes);
-
- if (BitDepth == 8)
- return 0xff & bytes[sample_index_bytes];
- else if (BitDepth < 8)
+ int pixelIndexBits = bitsPerPixel * pixelIndexInScanline;
+ int sampleIndexBits = pixelIndexBits + (sampleIndex * bitDepth);
+ int sampleIndexBytes = sampleIndexBits >> 3;
+
+ if (bitDepth == 8)
+ return 0xff & bytes[sampleIndexBytes];
+ else if (bitDepth < 8)
{
- int b = 0xff & bytes[sample_index_bytes];
- // int bits_to_shift = 8 - ((pixel_index_bits % 8) + BitsPerPixel);
- int bits_to_shift = 8 - ((pixel_index_bits & 7) + BitDepth);
- // int bits_to_shift = 8 - ((pixel_index_bits % 8) + BitDepth);
- b >>= bits_to_shift;
+ int b = 0xff & bytes[sampleIndexBytes];
+ int bitsToShift = 8 - ((pixelIndexBits & 7) + bitDepth);
+ b >>= bitsToShift;
- int bitmask = (1 << BitDepth) - 1;
+ int bitmask = (1 << bitDepth) - 1;
return b & bitmask;
- // switch (BitDepth)
- // {
- // case 1 :
- // return b & 1;
- // case 2 :
- // return b & 3;
- // case 4 :
- // return b & 15;
- // }
- }
- else if (BitDepth == 16)
+ } else if (bitDepth == 16)
{
- return ((0xff & (bytes[sample_index_bytes] << 8)) | (0xff & bytes[sample_index_bytes + 1]));
+ return (((0xff & bytes[sampleIndexBytes]) << 8) | (0xff & bytes[sampleIndexBytes + 1]));
}
- throw new ImageReadException("PNG: bad BitDepth: " + BitDepth);
+ throw new ImageReadException("PNG: bad BitDepth: " + bitDepth);
}
- public int getSampleAsByte(int pixel_index_in_scanline, int SampleIndex)
+ public int getSampleAsByte(int pixelIndexInScanline, int sampleIndex)
throws ImageReadException, IOException
{
- int sample = getSample(pixel_index_in_scanline, SampleIndex);
- int rot = 8 - BitDepth;
+ int sample = getSample(pixelIndexInScanline, sampleIndex);
+
+ int rot = 8 - bitDepth;
if (rot > 0)
sample <<= rot;
else if (rot < 0)
sample >>= -rot;
+
return 0xff & sample;
}
}
\ No newline at end of file
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/GammaCorrection.java Tue Jul 15 15:31:25 2008
@@ -20,42 +20,40 @@
{
private static final boolean DEBUG = false;
- // private final double src_gamma, dst_gamma;
- private final int lookup_table[];
+ private final int lookupTable[];
public GammaCorrection(double src_gamma, double dst_gamma)
{
- // this.src_gamma = src_gamma;
- // this.dst_gamma = dst_gamma;
+
if (DEBUG)
{
System.out.println("src_gamma: " + src_gamma);
System.out.println("dst_gamma: " + dst_gamma);
}
- lookup_table = new int[256];
+ lookupTable = new int[256];
for (int i = 0; i < 256; i++)
{
- lookup_table[i] = correctSample(i, src_gamma, dst_gamma);
+ lookupTable[i] = correctSample(i, src_gamma, dst_gamma);
if (DEBUG)
{
- System.out.println("lookup_table[" + i + "]: "
- + lookup_table[i]);
+ System.out
+ .println("lookup_table[" + i + "]: " + lookupTable[i]);
}
}
}
public int correctSample(int sample)
{
- return lookup_table[sample];
+ return lookupTable[sample];
}
public int correctARGB(int pixel)
{
int alpha = (0xff000000) & pixel;
- int red = (pixel & 0xff) >> 16;
- int green = (pixel & 0xff) >> 8;
- int blue = (pixel & 0xff) >> 0;
+ int red = (pixel >> 16) & 0xff;
+ int green = (pixel >> 8) & 0xff;
+ int blue = (pixel >> 0) & 0xff;
red = correctSample(red);
green = correctSample(green);
@@ -69,12 +67,12 @@
private int correctSample(int sample, double src_gamma, double dst_gamma)
{
- // if (kUseAdobeGammaMethod && val <= 32)
- // {
- // double slope = Math.round(255.0d * Math.pow((32.0 / 255.0d),
- // src_gamma / dst_gamma)) / 32.d;
- // return (int) (sample * slope);
- // }
+ // if (kUseAdobeGammaMethod && val <= 32)
+ // {
+ // double slope = Math.round(255.0d * Math.pow((32.0 / 255.0d),
+ // src_gamma / dst_gamma)) / 32.d;
+ // return (int) (sample * slope);
+ // }
return (int) Math.round(255.0d * Math.pow((sample / 255.0d), src_gamma
/ dst_gamma));
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngImageParser.java Tue Jul 15 15:31:25 2008
@@ -59,13 +59,14 @@
import org.apache.sanselan.icc.IccProfileParser;
import org.apache.sanselan.util.Debug;
import org.apache.sanselan.util.IOUtils;
+import org.apache.sanselan.util.ParamMap;
public class PngImageParser extends ImageParser implements PngConstants
{
public PngImageParser()
{
- // setDebug(true);
+ // setDebug(true);
}
public String getName()
@@ -80,9 +81,7 @@
private static final String DEFAULT_EXTENSION = ".png";
- private static final String ACCEPTED_EXTENSIONS[] = {
- DEFAULT_EXTENSION,
- };
+ private static final String ACCEPTED_EXTENSIONS[] = { DEFAULT_EXTENSION, };
protected String[] getAcceptedExtensions()
{
@@ -91,16 +90,15 @@
protected ImageFormat[] getAcceptedTypes()
{
- return new ImageFormat[]{
- ImageFormat.IMAGE_FORMAT_PNG, //
+ return new ImageFormat[] { ImageFormat.IMAGE_FORMAT_PNG, //
};
}
- // private final static int tRNS = CharsToQuad('t', 'R', 'N', 's');
+ // private final static int tRNS = CharsToQuad('t', 'R', 'N', 's');
private boolean keepChunk(int ChunkType, int ChunkTypes[])
{
- // System.out.println("keepChunk: ");
+ // System.out.println("keepChunk: ");
if (ChunkTypes == null)
return true;
@@ -137,8 +135,7 @@
{
bytes = readByteArray("Chunk Data", length, is,
"Not a Valid PNG File: Couldn't read Chunk Data.");
- }
- else
+ } else
skipBytes(is, length, "Not a Valid PNG File");
if (debug)
@@ -203,14 +200,12 @@
readSignature(is);
chunks = readChunks(is, ChunkTypes, return_after_first);
return chunks;
- }
- finally
+ } finally
{
try
{
is.close();
- }
- catch (Exception e)
+ } catch (Exception e)
{
Debug.debug(e);
}
@@ -220,13 +215,11 @@
public byte[] getICCProfileBytes(ByteSource byteSource, Map params)
throws ImageReadException, IOException
{
- ArrayList chunks = readChunks(byteSource, new int[]{
- iCCP,
- }, true);
+ ArrayList chunks = readChunks(byteSource, new int[] { iCCP, }, true);
if ((chunks == null) || (chunks.size() < 1))
{
- // throw new ImageReadException("Png: No chunks");
+ // throw new ImageReadException("Png: No chunks");
return null;
}
@@ -240,13 +233,10 @@
return (bytes);
}
- public Dimension getImageSize(ByteSource byteSource,
- Map params)
+ public Dimension getImageSize(ByteSource byteSource, Map params)
throws ImageReadException, IOException
{
- ArrayList chunks = readChunks(byteSource, new int[]{
- IHDR,
- }, true);
+ ArrayList chunks = readChunks(byteSource, new int[] { IHDR, }, true);
if ((chunks == null) || (chunks.size() < 1))
throw new ImageReadException("Png: No chunks");
@@ -272,9 +262,8 @@
public IImageMetadata getMetadata(ByteSource byteSource, Map params)
throws ImageReadException, IOException
{
- ArrayList chunks = readChunks(byteSource, new int[]{
- tEXt, zTXt,
- }, true);
+ ArrayList chunks = readChunks(byteSource, new int[] { tEXt, zTXt, },
+ true);
if ((chunks == null) || (chunks.size() < 1))
return null;
@@ -293,89 +282,97 @@
private boolean isGrayscale(int colorType) throws ImageReadException
{
- // Color type is a single-byte integer that describes the interpretation of the
- // image data. Color type codes represent sums of the following values:
- // 1 (palette used), 2 (color used), and 4 (alpha channel used).
- // Valid values are 0, 2, 3, 4, and 6.
- //
- // Bit depth restrictions for each color type are imposed to simplify implementations
- // and to prohibit combinations that do not compress well. Decoders must support all
- // valid combinations of bit depth and color type. The allowed combinations are:
- //
- // Color Allowed Interpretation
- // Type Bit Depths
+ // Color type is a single-byte integer that describes the interpretation
+ // of the
+ // image data. Color type codes represent sums of the following values:
+ // 1 (palette used), 2 (color used), and 4 (alpha channel used).
+ // Valid values are 0, 2, 3, 4, and 6.
+ //
+ // Bit depth restrictions for each color type are imposed to simplify
+ // implementations
+ // and to prohibit combinations that do not compress well. Decoders must
+ // support all
+ // valid combinations of bit depth and color type. The allowed
+ // combinations are:
+ //
+ // Color Allowed Interpretation
+ // Type Bit Depths
+ //
+ // 0 1,2,4,8,16 Each pixel is a grayscale sample.
+ //
+ // 2 8,16 Each pixel is an R,G,B triple.
//
- // 0 1,2,4,8,16 Each pixel is a grayscale sample.
+ // 3 1,2,4,8 Each pixel is a palette index;
+ // a PLTE chunk must appear.
//
- // 2 8,16 Each pixel is an R,G,B triple.
+ // 4 8,16 Each pixel is a grayscale sample,
+ // followed by an alpha sample.
//
- // 3 1,2,4,8 Each pixel is a palette index;
- // a PLTE chunk must appear.
- //
- // 4 8,16 Each pixel is a grayscale sample,
- // followed by an alpha sample.
- //
- // 6 8,16 Each pixel is an R,G,B triple,
- // followed by an alpha sample.
+ // 6 8,16 Each pixel is an R,G,B triple,
+ // followed by an alpha sample.
switch (colorType)
{
- case COLOR_TYPE_GREYSCALE :
- return true;
- case COLOR_TYPE_TRUE_COLOR :
- return false;
- case COLOR_TYPE_INDEXED_COLOR :
- return false;
- case COLOR_TYPE_GREYSCALE_WITH_ALPHA :
- return true;
- case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA :
- return false;
+ case COLOR_TYPE_GREYSCALE:
+ return true;
+ case COLOR_TYPE_TRUE_COLOR:
+ return false;
+ case COLOR_TYPE_INDEXED_COLOR:
+ return false;
+ case COLOR_TYPE_GREYSCALE_WITH_ALPHA:
+ return true;
+ case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA:
+ return false;
}
- // return -1;
+ // return -1;
throw new ImageReadException("PNG: unknown color type: " + colorType);
}
private int samplesPerPixel(int colorType) throws ImageReadException
{
- // Color type is a single-byte integer that describes the interpretation of the
- // image data. Color type codes represent sums of the following values:
- // 1 (palette used), 2 (color used), and 4 (alpha channel used).
- // Valid values are 0, 2, 3, 4, and 6.
+ // Color type is a single-byte integer that describes the interpretation
+ // of the
+ // image data. Color type codes represent sums of the following values:
+ // 1 (palette used), 2 (color used), and 4 (alpha channel used).
+ // Valid values are 0, 2, 3, 4, and 6.
+ //
+ // Bit depth restrictions for each color type are imposed to simplify
+ // implementations
+ // and to prohibit combinations that do not compress well. Decoders must
+ // support all
+ // valid combinations of bit depth and color type. The allowed
+ // combinations are:
+ //
+ // Color Allowed Interpretation
+ // Type Bit Depths
+ //
+ // 0 1,2,4,8,16 Each pixel is a grayscale sample.
+ //
+ // 2 8,16 Each pixel is an R,G,B triple.
//
- // Bit depth restrictions for each color type are imposed to simplify implementations
- // and to prohibit combinations that do not compress well. Decoders must support all
- // valid combinations of bit depth and color type. The allowed combinations are:
+ // 3 1,2,4,8 Each pixel is a palette index;
+ // a PLTE chunk must appear.
//
- // Color Allowed Interpretation
- // Type Bit Depths
+ // 4 8,16 Each pixel is a grayscale sample,
+ // followed by an alpha sample.
//
- // 0 1,2,4,8,16 Each pixel is a grayscale sample.
- //
- // 2 8,16 Each pixel is an R,G,B triple.
- //
- // 3 1,2,4,8 Each pixel is a palette index;
- // a PLTE chunk must appear.
- //
- // 4 8,16 Each pixel is a grayscale sample,
- // followed by an alpha sample.
- //
- // 6 8,16 Each pixel is an R,G,B triple,
- // followed by an alpha sample.
+ // 6 8,16 Each pixel is an R,G,B triple,
+ // followed by an alpha sample.
switch (colorType)
{
- case COLOR_TYPE_GREYSCALE :
- return 1;
- case COLOR_TYPE_TRUE_COLOR :
- return 3;
- case COLOR_TYPE_INDEXED_COLOR :
- return 1; // is this accurate ? how may bits per index?
- case COLOR_TYPE_GREYSCALE_WITH_ALPHA :
- return 2;
- case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA :
- return 4;
+ case COLOR_TYPE_GREYSCALE:
+ return 1;
+ case COLOR_TYPE_TRUE_COLOR:
+ return 3;
+ case COLOR_TYPE_INDEXED_COLOR:
+ return 1; // is this accurate ? how may bits per index?
+ case COLOR_TYPE_GREYSCALE_WITH_ALPHA:
+ return 2;
+ case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA:
+ return 4;
}
- // return -1;
+ // return -1;
throw new ImageReadException("PNG: unknown color type: " + colorType);
}
@@ -398,18 +395,21 @@
{
switch (ColorType)
{
- case COLOR_TYPE_GREYSCALE : // 1,2,4,8,16 Each pixel is a grayscale sample.
- case COLOR_TYPE_TRUE_COLOR : // 8,16 Each pixel is an R,G,B triple.
- case COLOR_TYPE_INDEXED_COLOR : // 1,2,4,8 Each pixel is a palette index;
- return false;
- case COLOR_TYPE_GREYSCALE_WITH_ALPHA : // 8,16 Each pixel is a grayscale sample,
- // followed by an alpha sample.
- case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : // 8,16 Each pixel is an R,G,B triple,
- // followed by an alpha sample.
- return true;
- default :
- throw new ImageReadException("PNG: unknown color type: "
- + ColorType);
+ case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+ // sample.
+ case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+ case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index;
+ return false;
+ case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale
+ // sample,
+ // followed by an alpha sample.
+ case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B
+ // triple,
+ // followed by an alpha sample.
+ return true;
+ default:
+ throw new ImageReadException("PNG: unknown color type: "
+ + ColorType);
}
}
@@ -417,58 +417,64 @@
{
switch (ColorType)
{
- case COLOR_TYPE_GREYSCALE : // 1,2,4,8,16 Each pixel is a grayscale sample.
- return "grayscale";
- case COLOR_TYPE_TRUE_COLOR : // 8,16 Each pixel is an R,G,B triple.
- return "rgb";
- case COLOR_TYPE_INDEXED_COLOR : // 1,2,4,8 Each pixel is a palette index;
- return "indexed rgb";
- case COLOR_TYPE_GREYSCALE_WITH_ALPHA : // 8,16 Each pixel is a grayscale sample,
- // followed by an alpha sample.
- return "grayscale w/ alpha";
- case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : // 8,16 Each pixel is an R,G,B triple,
- // followed by an alpha sample.
- return "RGB w/ alpha";
- default :
- return "Unknown Color Type";
+ case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+ // sample.
+ return "grayscale";
+ case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+ return "rgb";
+ case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index;
+ return "indexed rgb";
+ case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale
+ // sample,
+ // followed by an alpha sample.
+ return "grayscale w/ alpha";
+ case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B
+ // triple,
+ // followed by an alpha sample.
+ return "RGB w/ alpha";
+ default:
+ return "Unknown Color Type";
}
}
- // TODO: I have been too casual about making inner classes subclass of BinaryFileParser
+ // TODO: I have been too casual about making inner classes subclass of
+ // BinaryFileParser
// I may not have always preserved byte order correctly.
private TransparencyFilter getTransparencyFilter(int ColorType,
PNGChunk pngChunktRNS) throws ImageReadException, IOException
{
- // this.printCharQuad("pngChunktRNS.ChunkType", pngChunktRNS.ChunkType);
- // this.debugNumber("pngChunktRNS.Length", pngChunktRNS.Length);
+ // this.printCharQuad("pngChunktRNS.ChunkType", pngChunktRNS.ChunkType);
+ // this.debugNumber("pngChunktRNS.Length", pngChunktRNS.Length);
switch (ColorType)
{
- case COLOR_TYPE_GREYSCALE : // 1,2,4,8,16 Each pixel is a grayscale sample.
- return new TransparencyFilterGrayscale(pngChunktRNS.bytes);
- case COLOR_TYPE_TRUE_COLOR : // 8,16 Each pixel is an R,G,B triple.
- return new TransparencyFilterTrueColor(pngChunktRNS.bytes);
- case COLOR_TYPE_INDEXED_COLOR : // 1,2,4,8 Each pixel is a palette index;
- return new TransparencyFilterIndexedColor(pngChunktRNS.bytes);
- case COLOR_TYPE_GREYSCALE_WITH_ALPHA : // 8,16 Each pixel is a grayscale sample,
- case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : // 8,16 Each pixel is an R,G,B triple,
- default :
- throw new ImageReadException(
- "Simple Transparency not compatible with ColorType: "
- + ColorType);
+ case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+ // sample.
+ return new TransparencyFilterGrayscale(pngChunktRNS.bytes);
+ case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+ return new TransparencyFilterTrueColor(pngChunktRNS.bytes);
+ case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette index;
+ return new TransparencyFilterIndexedColor(pngChunktRNS.bytes);
+ case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a grayscale
+ // sample,
+ case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an R,G,B
+ // triple,
+ default:
+ throw new ImageReadException(
+ "Simple Transparency not compatible with ColorType: "
+ + ColorType);
}
}
public ImageInfo getImageInfo(ByteSource byteSource, Map params)
throws ImageReadException, IOException
{
- ArrayList chunks = readChunks(byteSource, new int[]{
- IHDR, pHYs, tEXt, zTXt, tRNS, PLTE,
- }, false);
+ ArrayList chunks = readChunks(byteSource, new int[] { IHDR, pHYs, tEXt,
+ zTXt, tRNS, PLTE, }, false);
- // if(chunks!=null)
- // System.out.println("chunks: " + chunks.size());
+ // if(chunks!=null)
+ // System.out.println("chunks: " + chunks.size());
if ((chunks == null) || (chunks.size() < 1))
throw new ImageReadException("PNG: no chunks");
@@ -487,8 +493,7 @@
{
isTransparent = true;
pngChunktRNS = (PNGChunk) IHDRs.get(0);
- }
- else
+ } else
hasAlphaChannel(pngChunkIHDR.colorType);
PNGChunkpHYs pngChunkpHYs = null;
@@ -503,22 +508,22 @@
ArrayList tEXts = filterChunks(chunks, tEXt);
ArrayList zTXts = filterChunks(chunks, zTXt);
- // private class PNGChunkpHYs extends PNGChunk
- // {
- // public final int PixelsPerUnitXAxis;
- // public final int PixelsPerUnitYAxis;
- // public final int UnitSpecifier;
-
- {
- // private class PNGChunkIHDR extends PNGChunk
- // {
- // public final int Width;
- // public final int Height;
- // public final int BitDepth;
- // public final int ColorType;
- // public final int CompressionMethod;
- // public final int FilterMethod;
- // public final int InterlaceMethod;
+ // private class PNGChunkpHYs extends PNGChunk
+ // {
+ // public final int PixelsPerUnitXAxis;
+ // public final int PixelsPerUnitYAxis;
+ // public final int UnitSpecifier;
+
+ {
+ // private class PNGChunkIHDR extends PNGChunk
+ // {
+ // public final int Width;
+ // public final int Height;
+ // public final int BitDepth;
+ // public final int ColorType;
+ // public final int CompressionMethod;
+ // public final int FilterMethod;
+ // public final int InterlaceMethod;
ArrayList Comments = new ArrayList();
@@ -548,12 +553,15 @@
int PhysicalWidthDpi = -1;
float PhysicalWidthInch = -1;
- // if (pngChunkpHYs != null)
- // {
- // System.out.println("\t" + "pngChunkpHYs.UnitSpecifier: " + pngChunkpHYs.UnitSpecifier );
- // System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitYAxis: " + pngChunkpHYs.PixelsPerUnitYAxis );
- // System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitXAxis: " + pngChunkpHYs.PixelsPerUnitXAxis );
- // }
+ // if (pngChunkpHYs != null)
+ // {
+ // System.out.println("\t" + "pngChunkpHYs.UnitSpecifier: " +
+ // pngChunkpHYs.UnitSpecifier );
+ // System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitYAxis: " +
+ // pngChunkpHYs.PixelsPerUnitYAxis );
+ // System.out.println("\t" + "pngChunkpHYs.PixelsPerUnitXAxis: " +
+ // pngChunkpHYs.PixelsPerUnitXAxis );
+ // }
if ((pngChunkpHYs != null) && (pngChunkpHYs.UnitSpecifier == 1)) // meters
{
double meters_per_inch = 0.0254;
@@ -581,20 +589,24 @@
int ColorType;
switch (pngChunkIHDR.colorType)
{
- case COLOR_TYPE_GREYSCALE : // 1,2,4,8,16 Each pixel is a grayscale sample.
- case COLOR_TYPE_GREYSCALE_WITH_ALPHA : // 8,16 Each pixel is a grayscale sample,
- // followed by an alpha sample.
- ColorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
- break;
- case COLOR_TYPE_TRUE_COLOR : // 8,16 Each pixel is an R,G,B triple.
- case COLOR_TYPE_INDEXED_COLOR : // 1,2,4,8 Each pixel is a palette index;
- case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA : // 8,16 Each pixel is an R,G,B triple,
- // followed by an alpha sample.
- ColorType = ImageInfo.COLOR_TYPE_RGB;
- break;
- default :
- throw new ImageReadException("Png: Unknown ColorType: "
- + pngChunkIHDR.colorType);
+ case COLOR_TYPE_GREYSCALE: // 1,2,4,8,16 Each pixel is a grayscale
+ // sample.
+ case COLOR_TYPE_GREYSCALE_WITH_ALPHA: // 8,16 Each pixel is a
+ // grayscale sample,
+ // followed by an alpha sample.
+ ColorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
+ break;
+ case COLOR_TYPE_TRUE_COLOR: // 8,16 Each pixel is an R,G,B triple.
+ case COLOR_TYPE_INDEXED_COLOR: // 1,2,4,8 Each pixel is a palette
+ // index;
+ case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA: // 8,16 Each pixel is an
+ // R,G,B triple,
+ // followed by an alpha sample.
+ ColorType = ImageInfo.COLOR_TYPE_RGB;
+ break;
+ default:
+ throw new ImageReadException("Png: Unknown ColorType: "
+ + pngChunkIHDR.colorType);
}
String compressionAlgorithm = ImageInfo.COMPRESSION_ALGORITHM_PNG_FILTER;
@@ -612,9 +624,20 @@
public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
throws ImageReadException, IOException
{
- ArrayList chunks = readChunks(byteSource, new int[]{
- IHDR, PLTE, IDAT, tRNS, iCCP, gAMA, sRGB,
- }, false);
+
+ boolean verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
+ false);
+
+ if (params.containsKey(PARAM_KEY_VERBOSE))
+ params.remove(PARAM_KEY_VERBOSE);
+
+ // if (params.size() > 0) {
+ // Object firstKey = params.keySet().iterator().next();
+ // throw new ImageWriteException("Unknown parameter: " + firstKey);
+ // }
+
+ ArrayList chunks = readChunks(byteSource, new int[] { IHDR, PLTE, IDAT,
+ tRNS, iCCP, gAMA, sRGB, }, false);
if ((chunks == null) || (chunks.size() < 1))
throw new ImageReadException("PNG: no chunks");
@@ -644,7 +667,7 @@
{
PNGChunkIDAT pngChunkIDAT = (PNGChunkIDAT) IDATs.get(i);
byte bytes[] = pngChunkIDAT.bytes;
- // System.out.println(i + ": bytes: " + bytes.length);
+ // System.out.println(i + ": bytes: " + bytes.length);
baos.write(bytes);
}
@@ -680,8 +703,7 @@
// no color management neccesary.
if (debug)
System.out.println("sRGB, no color management neccesary.");
- }
- else if (iCCPs.size() == 1)
+ } else if (iCCPs.size() == 1)
{
if (debug)
System.out.println("iCCP.");
@@ -690,16 +712,13 @@
byte bytes[] = pngChunkiCCP.UncompressedProfile;
icc_profile = ICC_Profile.getInstance(bytes);
- }
- else if (gAMAs.size() == 1)
+ } else if (gAMAs.size() == 1)
{
PNGChunkgAMA pngChunkgAMA = (PNGChunkgAMA) gAMAs.get(0);
double gamma = pngChunkgAMA.getGamma();
- // if (debug)
- // System.out.println("gamma: " + gamma);
// charles: what is the correct target value here?
- // double targetGamma = 2.2;
+ // double targetGamma = 2.2;
double targetGamma = 1.0;
double diff = Math.abs(targetGamma - gamma);
if (diff >= 0.5)
@@ -718,115 +737,16 @@
int colorType = pngChunkIHDR.colorType;
int bitDepth = pngChunkIHDR.bitDepth;
- // System.out.println("color_type: " + color_type);
- // System.out.println("BitDepth: " + BitDepth);
-
- // int transfer_type;
- // int BytesPerSample;
int bitsPerSample = bitDepth;
if (pngChunkIHDR.filterMethod != 0)
throw new ImageReadException("PNG: unknown FilterMethod: "
+ pngChunkIHDR.filterMethod);
- // transfer_type = DataBuffer.TYPE_BYTE;
- // switch (BitDepth)
- // {
- // case 1 :
- // case 2 :
- // case 4 :
- // case 8 :
- // transfer_type = DataBuffer.TYPE_BYTE;
- // // BytesPerSample = 1;
- // break;
- // case 16 :
- // transfer_type = DataBuffer.TYPE_INT;
- // // BytesPerSample = 2;
- // break;
- // default :
- // throw new ImageReadException("PNG: unknown bit depth: " + BitDepth);
- // }
-
- // ColorModel cm = null;
int samplesPerPixel = samplesPerPixel(pngChunkIHDR.colorType);
boolean isGrayscale = isGrayscale(pngChunkIHDR.colorType);
- // switch (colorType)
- // {
- // case 0 : // 1,2,4,8,16 Each pixel is a grayscale sample.
- // {
- // ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
- //
- // // BytesPerPixel = getBytesPerPixel( BitsPerSample, SamplesPerPixel);
- // // BytesPerPixel = BytesPerSample * SamplesPerPixel;
- // cm = new ComponentColorModel(cs, true, false,
- // ColorModel.TRANSLUCENT, transfer_type);
- // break;
- // }
- // case 2 : // 8,16 Each pixel is an R,G,B triple.
- // {
- // ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
- //
- // // BytesPerPixel = getBytesPerPixel( BitsPerSample, SamplesPerPixel);
- // // BytesPerPixel = BytesPerSample * SamplesPerPixel;
- // cm = new ComponentColorModel(cs, true, false,
- // ColorModel.TRANSLUCENT, transfer_type);
- // // cm = ColorModel.getRGBdefault();
- // break;
- // }
- // //
- // case 3 : // 1,2,4,8 Each pixel is a palette index;
- // // a PLTE chunk must appear.
- // {
- // ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
- //
- // // BytesPerPixel = getBytesPerPixel( BitsPerSample, SamplesPerPixel);
- // // BytesPerPixel = BytesPerSample * SamplesPerPixel;
- // cm = new ComponentColorModel(cs, true, false,
- // ColorModel.TRANSLUCENT, transfer_type);
- // // cm = ColorModel.getRGBdefault();
- //
- // // SamplesPerPixel = 1;
- // // // bits_per_pixel = 8;
- // // // BytesPerPixel = 1;
- // // cm = ColorModel.getRGBdefault();
- // // // ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
- // // // cm = new ComponentColorModel(cs, false, false,
- // // // ColorModel.OPAQUE, transfer_type);
- // break;
- // }
- // case 4 : // 8,16 Each pixel is a grayscale sample,
- // // followed by an alpha sample.
- // {
- // ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
- //
- // // BytesPerPixel = getBytesPerPixel( BitsPerSample, SamplesPerPixel);
- // // BytesPerPixel = BytesPerSample * SamplesPerPixel;
- // cm = new ComponentColorModel(cs, true, false,
- // ColorModel.TRANSLUCENT, transfer_type);
- // break;
- // }
- // case 6 : // 8,16 Each pixel is an R,G,B triple,
- // {
- // ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
- //
- // // BytesPerPixel = getBytesPerPixel( BitsPerSample, SamplesPerPixel);
- // // BytesPerPixel = BytesPerSample * SamplesPerPixel;
- // cm = new ComponentColorModel(cs, true, false,
- // ColorModel.TRANSLUCENT, transfer_type);
- // break;
- // }
- // default :
- // throw new ImageReadException("PNG: unknown color type: "
- // + BitDepth);
- // }
-
- // cm = ColorModel.getRGBdefault();
- //
-
int bitsPerPixel = bitsPerSample * samplesPerPixel;
- // Debug.debug("bitsPerSample", bitsPerSample);
- // Debug.debug("samplesPerPixel", samplesPerPixel);
boolean hasAlpha = colorType == COLOR_TYPE_GREYSCALE_WITH_ALPHA
|| colorType == COLOR_TYPE_TRUE_COLOR_WITH_ALPHA;
@@ -842,19 +762,6 @@
ByteArrayInputStream bais = new ByteArrayInputStream(compressed);
InflaterInputStream iis = new InflaterInputStream(bais);
- byte bytes[] = IOUtils.getInputStreamBytes(iis);
-
- bais = new ByteArrayInputStream(compressed);
- iis = new InflaterInputStream(bais);
-
- // ZInputStream iis = new ZInputStream(bais);
- // ByteArrayInputStream iis = new ByteArrayInputStream(uncompressed);
-
- // int bitsPerScanLine = bitsPerPixel * width;
-
- // Debug.debug("bitsPerScanLine", bitsPerScanLine);
- // Debug.debug("bitsPerPixel", bitsPerPixel);
-
ScanExpediter scanExpediter;
if (pngChunkIHDR.interlaceMethod == 0)
Modified: incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java
URL: http://svn.apache.org/viewvc/incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java?rev=677073&r1=677072&r2=677073&view=diff
==============================================================================
--- incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java (original)
+++ incubator/sanselan/trunk/src/main/java/org/apache/sanselan/formats/png/PngWriter.java Tue Jul 15 15:31:25 2008
@@ -29,51 +29,38 @@
import org.apache.sanselan.palette.Palette;
import org.apache.sanselan.palette.PaletteFactory;
import org.apache.sanselan.util.Debug;
+import org.apache.sanselan.util.ParamMap;
-public class PngWriter implements PngConstants
-{
+public class PngWriter implements PngConstants {
private final boolean verbose;
- public PngWriter(boolean verbose)
- {
+ public PngWriter(boolean verbose) {
this.verbose = verbose;
}
- public PngWriter(Map params)
- {
- this.verbose = getParamBoolean(params, PARAM_KEY_VERBOSE, false);
- }
-
- private boolean getParamBoolean(Map params, Object key,
- boolean default_value)
- {
- boolean result = default_value;
- {
- Object o = params == null ? null : params.get(key);
- if (o != null && o instanceof Boolean)
- result = ((Boolean) o).booleanValue();
- }
- return result;
+ public PngWriter(Map params) {
+ this.verbose = ParamMap.getParamBoolean(params, PARAM_KEY_VERBOSE,
+ false);
}
/*
- 1. IHDR: image header, which is the first chunk in a PNG datastream.
- 2. PLTE: palette table associated with indexed PNG images.
- 3. IDAT: image data chunks.
- 4. IEND: image trailer, which is the last chunk in a PNG datastream.
-
- The remaining 14 chunk types are termed ancillary chunk types, which encoders may generate and decoders may interpret.
-
- 1. Transparency information: tRNS (see 11.3.2: Transparency information).
- 2. Colour space information: cHRM, gAMA, iCCP, sBIT, sRGB (see 11.3.3: Colour space information).
- 3. Textual information: iTXt, tEXt, zTXt (see 11.3.4: Textual information).
- 4. Miscellaneous information: bKGD, hIST, pHYs, sPLT (see 11.3.5: Miscellaneous information).
- 5. Time information: tIME (see 11.3.6: Time stamp information).
-
+ * 1. IHDR: image header, which is the first chunk in a PNG datastream. 2.
+ * PLTE: palette table associated with indexed PNG images. 3. IDAT: image
+ * data chunks. 4. IEND: image trailer, which is the last chunk in a PNG
+ * datastream.
+ *
+ * The remaining 14 chunk types are termed ancillary chunk types, which
+ * encoders may generate and decoders may interpret.
+ *
+ * 1. Transparency information: tRNS (see 11.3.2: Transparency information).
+ * 2. Colour space information: cHRM, gAMA, iCCP, sBIT, sRGB (see 11.3.3:
+ * Colour space information). 3. Textual information: iTXt, tEXt, zTXt (see
+ * 11.3.4: Textual information). 4. Miscellaneous information: bKGD, hIST,
+ * pHYs, sPLT (see 11.3.5: Miscellaneous information). 5. Time information:
+ * tIME (see 11.3.6: Time stamp information).
*/
- private final void writeInt(OutputStream os, int value) throws IOException
- {
+ private final void writeInt(OutputStream os, int value) throws IOException {
os.write(0xff & (value >> 24));
os.write(0xff & (value >> 16));
os.write(0xff & (value >> 8));
@@ -81,16 +68,15 @@
}
private final void writeChunk(OutputStream os, byte chunk_type[],
- byte data[]) throws IOException
- {
+ byte data[]) throws IOException {
int data_length = data == null ? 0 : data.length;
writeInt(os, data_length);
os.write(chunk_type);
if (data != null)
os.write(data);
- // Debug.debug("writeChunk chunk_type", chunk_type);
- // Debug.debug("writeChunk data", data);
+ // Debug.debug("writeChunk chunk_type", chunk_type);
+ // Debug.debug("writeChunk data", data);
{
PngCrc png_crc = new PngCrc();
@@ -101,19 +87,18 @@
crc1, data, data.length);
int crc = (int) png_crc.finish_partial_crc(crc2);
- // Debug.debug("crc1", crc1 + " (" + Long.toHexString(crc1)
- // + ")");
- // Debug.debug("crc2", crc2 + " (" + Long.toHexString(crc2)
- // + ")");
- // Debug.debug("crc3", crc + " (" + Integer.toHexString(crc)
- // + ")");
+ // Debug.debug("crc1", crc1 + " (" + Long.toHexString(crc1)
+ // + ")");
+ // Debug.debug("crc2", crc2 + " (" + Long.toHexString(crc2)
+ // + ")");
+ // Debug.debug("crc3", crc + " (" + Integer.toHexString(crc)
+ // + ")");
writeInt(os, crc);
}
}
- private static class ImageHeader
- {
+ private static class ImageHeader {
public final int width;
public final int height;
public final byte bit_depth;
@@ -124,8 +109,7 @@
public ImageHeader(int width, int height, byte bit_depth,
byte colorType, byte compression_method, byte filter_method,
- byte interlace_method)
- {
+ byte interlace_method) {
this.width = width;
this.height = height;
this.bit_depth = bit_depth;
@@ -138,8 +122,7 @@
}
private void writeChunkIHDR(OutputStream os, ImageHeader value)
- throws IOException
- {
+ throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
writeInt(baos, value.width);
writeInt(baos, value.height);
@@ -149,23 +132,21 @@
baos.write(0xff & value.filter_method);
baos.write(0xff & value.interlace_method);
- // Debug.debug("baos", baos.toByteArray());
+ // Debug.debug("baos", baos.toByteArray());
writeChunk(os, IHDR_CHUNK_TYPE, baos.toByteArray());
}
private void writeChunkPLTE(OutputStream os, Palette palette)
- throws IOException
- {
+ throws IOException {
int length = palette.length();
byte bytes[] = new byte[length * 3];
- // Debug.debug("length", length);
- for (int i = 0; i < length; i++)
- {
+ // Debug.debug("length", length);
+ for (int i = 0; i < length; i++) {
int rgb = palette.getEntry(i);
int index = i * 3;
- // Debug.debug("index", index);
+ // Debug.debug("index", index);
bytes[index + 0] = (byte) (0xff & (rgb >> 16));
bytes[index + 1] = (byte) (0xff & (rgb >> 8));
bytes[index + 2] = (byte) (0xff & (rgb >> 0));
@@ -174,33 +155,28 @@
writeChunk(os, PLTE_CHUNK_TYPE, bytes);
}
- private void writeChunkIEND(OutputStream os) throws IOException
- {
+ private void writeChunkIEND(OutputStream os) throws IOException {
writeChunk(os, IEND_CHUNK_TYPE, null);
}
private void writeChunkIDAT(OutputStream os, byte bytes[])
- throws IOException
- {
+ throws IOException {
writeChunk(os, IDAT_CHUNK_TYPE, bytes);
}
- private byte getColourType(boolean hasAlpha, boolean isGrayscale)
- {
+ private byte getColourType(boolean hasAlpha, boolean isGrayscale) {
byte result;
boolean index = false; // charles
if (index)
result = COLOR_TYPE_INDEXED_COLOR;
- else if (isGrayscale)
- {
+ else if (isGrayscale) {
if (hasAlpha)
result = COLOR_TYPE_GREYSCALE_WITH_ALPHA;
else
result = COLOR_TYPE_GREYSCALE;
- }
- else if (hasAlpha)
+ } else if (hasAlpha)
result = COLOR_TYPE_TRUE_COLOR_WITH_ALPHA;
else
result = COLOR_TYPE_TRUE_COLOR;
@@ -208,37 +184,33 @@
return result;
}
- private byte getBitDepth(final byte colorType, Map params)
- {
+ private byte getBitDepth(final byte colorType, Map params) {
byte result = 8;
Object o = params.get(PARAM_KEY_PNG_BIT_DEPTH);
- if (o != null && o instanceof Number)
- {
+ if (o != null && o instanceof Number) {
int value = ((Number) o).intValue();
- switch (value)
- {
- case 1 :
- case 2 :
- case 4 :
- case 8 :
- case 16 :
- result = (byte) value;
- default :
+ switch (value) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ result = (byte) value;
+ default:
}
- switch (colorType)
- {
- case COLOR_TYPE_GREYSCALE :
- break;
- case COLOR_TYPE_INDEXED_COLOR :
- result = (byte) Math.min(8, result);
- break;
- case COLOR_TYPE_GREYSCALE_WITH_ALPHA :
- case COLOR_TYPE_TRUE_COLOR :
- case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA :
- result = (byte) Math.max(8, result);
- break;
- default :
+ switch (colorType) {
+ case COLOR_TYPE_GREYSCALE:
+ break;
+ case COLOR_TYPE_INDEXED_COLOR:
+ result = (byte) Math.min(8, result);
+ break;
+ case COLOR_TYPE_GREYSCALE_WITH_ALPHA:
+ case COLOR_TYPE_TRUE_COLOR:
+ case COLOR_TYPE_TRUE_COLOR_WITH_ALPHA:
+ result = (byte) Math.max(8, result);
+ break;
+ default:
}
}
@@ -246,36 +218,23 @@
}
/*
- between two chunk types indicates alternatives.
- Table 5.3 Chunk ordering rules Critical chunks
- (shall appear in this order, except PLTE is optional)
- Chunk name Multiple allowed Ordering constraints
- IHDR No Shall be first
- PLTE No Before first IDAT
- IDAT Yes Multiple IDAT chunks shall be consecutive
- IEND No Shall be last
- Ancillary chunks
- (need not appear in this order)
- Chunk name Multiple allowed Ordering constraints
- cHRM No Before PLTE and IDAT
- gAMA No Before PLTE and IDAT
- iCCP No Before PLTE and IDAT. If the iCCP chunk is present, the sRGB chunk should not be present.
- sBIT No Before PLTE and IDAT
- sRGB No Before PLTE and IDAT. If the sRGB chunk is present, the iCCP chunk should not be present.
- bKGD No After PLTE; before IDAT
- hIST No After PLTE; before IDAT
- tRNS No After PLTE; before IDAT
- pHYs No Before IDAT
- sPLT Yes Before IDAT
- tIME No None
- iTXt Yes None
- tEXt Yes None
- zTXt Yes None
+ * between two chunk types indicates alternatives. Table 5.3 Chunk
+ * ordering rules Critical chunks (shall appear in this order, except PLTE
+ * is optional) Chunk name Multiple allowed Ordering constraints IHDR No
+ * Shall be first PLTE No Before first IDAT IDAT Yes Multiple IDAT chunks
+ * shall be consecutive IEND No Shall be last Ancillary chunks (need not
+ * appear in this order) Chunk name Multiple allowed Ordering constraints
+ * cHRM No Before PLTE and IDAT gAMA No Before PLTE and IDAT iCCP No Before
+ * PLTE and IDAT. If the iCCP chunk is present, the sRGB chunk should not be
+ * present. sBIT No Before PLTE and IDAT sRGB No Before PLTE and IDAT. If
+ * the sRGB chunk is present, the iCCP chunk should not be present. bKGD No
+ * After PLTE; before IDAT hIST No After PLTE; before IDAT tRNS No After
+ * PLTE; before IDAT pHYs No Before IDAT sPLT Yes Before IDAT tIME No None
+ * iTXt Yes None tEXt Yes None zTXt Yes None
*/
public void writeImage(BufferedImage src, OutputStream os, Map params)
- throws ImageWriteException, IOException
- {
+ throws ImageWriteException, IOException {
// make copy of params; we'll clear keys as we consume them.
params = new HashMap(params);
@@ -293,8 +252,7 @@
params.remove(PARAM_KEY_PNG_FORCE_INDEXED_COLOR);
if (params.containsKey(PARAM_KEY_PNG_BIT_DEPTH))
params.remove(PARAM_KEY_PNG_BIT_DEPTH);
- if (params.size() > 0)
- {
+ if (params.size() > 0) {
Object firstKey = params.keySet().iterator().next();
throw new ImageWriteException("Unknown parameter: " + firstKey);
}
@@ -306,7 +264,7 @@
boolean hasAlpha = new PaletteFactory().hasTransparency(src);
if (verbose)
Debug.debug("hasAlpha", hasAlpha);
- // int transparency = new PaletteFactory().getTransparency(src);
+ // int transparency = new PaletteFactory().getTransparency(src);
boolean isGrayscale = new PaletteFactory().isGrayscale(src);
if (verbose)
@@ -314,25 +272,20 @@
byte colorType;
{
- boolean force_indexed_color = getParamBoolean(params,
+ boolean force_indexed_color = ParamMap.getParamBoolean(params,
PARAM_KEY_PNG_FORCE_INDEXED_COLOR, false);
- boolean force_true_color = getParamBoolean(params,
+ boolean force_true_color = ParamMap.getParamBoolean(params,
PARAM_KEY_PNG_FORCE_TRUE_COLOR, false);
if (force_indexed_color && force_true_color)
throw new ImageWriteException(
"Params: Cannot force both indexed and true color modes");
- else if (force_indexed_color)
- {
+ else if (force_indexed_color) {
colorType = COLOR_TYPE_INDEXED_COLOR;
- }
- else if (force_true_color)
- {
- colorType = (byte) (hasAlpha
- ? COLOR_TYPE_TRUE_COLOR_WITH_ALPHA
+ } else if (force_true_color) {
+ colorType = (byte) (hasAlpha ? COLOR_TYPE_TRUE_COLOR_WITH_ALPHA
: COLOR_TYPE_TRUE_COLOR);
- }
- else
+ } else
colorType = getColourType(hasAlpha, isGrayscale);
if (verbose)
Debug.debug("colorType", colorType);
@@ -354,7 +307,7 @@
os.write(PNG_Signature);
}
{
- // IHDR Shall be first
+ // IHDR Shall be first
byte compression_method = COMPRESSION_TYPE_INFLATE_DEFLATE;
byte filter_method = FILTER_METHOD_ADAPTIVE;
@@ -368,32 +321,32 @@
}
{
- // sRGB No Before PLTE and IDAT. If the sRGB chunk is present, the iCCP chunk should not be present.
+ // sRGB No Before PLTE and IDAT. If the sRGB chunk is present, the
+ // iCCP chunk should not be present.
// charles
}
Palette palette = null;
- if (colorType == COLOR_TYPE_INDEXED_COLOR)
- {
- // PLTE No Before first IDAT
+ if (colorType == COLOR_TYPE_INDEXED_COLOR) {
+ // PLTE No Before first IDAT
int max_colors = hasAlpha ? 255 : 256;
palette = new MedianCutQuantizer(true).process(src, max_colors,
verbose);
- // Palette palette2 = new PaletteFactory().makePaletteSimple(src,
- // max_colors);
+ // Palette palette2 = new PaletteFactory().makePaletteSimple(src,
+ // max_colors);
- // palette.dump();
+ // palette.dump();
writeChunkPLTE(os, palette);
}
{
- // Debug.debug("writing IDAT");
+ // Debug.debug("writing IDAT");
- // IDAT Yes Multiple IDAT chunks shall be consecutive
+ // IDAT Yes Multiple IDAT chunks shall be consecutive
byte uncompressed[];
{
@@ -403,44 +356,38 @@
|| colorType == COLOR_TYPE_TRUE_COLOR_WITH_ALPHA;
int row[] = new int[width];
- for (int y = 0; y < height; y++)
- {
- // Debug.debug("y", y + "/" + height);
+ for (int y = 0; y < height; y++) {
+ // Debug.debug("y", y + "/" + height);
src.getRGB(0, y, width, 1, row, 0, width);
byte filter_type = FILTER_TYPE_NONE;
baos.write(filter_type);
- for (int x = 0; x < width; x++)
- {
+ for (int x = 0; x < width; x++) {
int argb = row[x];
- if (palette != null)
- {
+ if (palette != null) {
int index = palette.getPaletteIndex(argb);
baos.write(0xff & index);
- }
- else
- {
+ } else {
int alpha = 0xff & (argb >> 24);
int red = 0xff & (argb >> 16);
int green = 0xff & (argb >> 8);
int blue = 0xff & (argb >> 0);
- if (isGrayscale)
- {
+ if (isGrayscale) {
int gray = (red + green + blue) / 3;
- // if(y==0)
- // {
- // Debug.debug(x + ", " + y + " argb", Integer.toHexString(argb));
- //// Debug.debug(x + ", " + y + " gray", gray);
- //// Debug.debug(x + ", " + y + " gray", gray);
- // Debug.debug(x + ", " + y + " gray", gray + " " + Integer.toHexString(gray));
- // Debug.debug();
- // }
+ // if(y==0)
+ // {
+ // Debug.debug(x + ", " + y + " argb",
+ // Integer.toHexString(argb));
+ // // Debug.debug(x + ", " + y + " gray", gray);
+ // // Debug.debug(x + ", " + y + " gray", gray);
+ // Debug.debug(x + ", " + y + " gray", gray +
+ // " " + Integer.toHexString(gray));
+ // Debug.debug();
+ // }
baos.write(gray);
- }
- else
- {
+ } else {
baos.write(red);
baos.write(green);
baos.write(blue);
@@ -453,13 +400,12 @@
}
uncompressed = baos.toByteArray();
}
- // Debug.debug("uncompressed", uncompressed.length);
+ // Debug.debug("uncompressed", uncompressed.length);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(baos);
int chunk_size = 256 * 1024;
- for (int index = 0; index < uncompressed.length; index += chunk_size)
- {
+ for (int index = 0; index < uncompressed.length; index += chunk_size) {
int end = Math.min(uncompressed.length, index + chunk_size);
int length = end - index;
@@ -469,9 +415,8 @@
byte compressed[] = baos.toByteArray();
baos.reset();
- if (compressed.length > 0)
- {
- // Debug.debug("compressed", compressed.length);
+ if (compressed.length > 0) {
+ // Debug.debug("compressed", compressed.length);
writeChunkIDAT(os, compressed);
}
@@ -479,38 +424,29 @@
{
dos.finish();
byte compressed[] = baos.toByteArray();
- if (compressed.length > 0)
- {
- // Debug.debug("compressed final", compressed.length);
+ if (compressed.length > 0) {
+ // Debug.debug("compressed final", compressed.length);
writeChunkIDAT(os, compressed);
}
}
}
{
- // IEND No Shall be last
+ // IEND No Shall be last
writeChunkIEND(os);
}
/*
- Ancillary chunks
- (need not appear in this order)
- Chunk name Multiple allowed Ordering constraints
- cHRM No Before PLTE and IDAT
- gAMA No Before PLTE and IDAT
- iCCP No Before PLTE and IDAT. If the iCCP chunk is present, the sRGB chunk should not be present.
- sBIT No Before PLTE and IDAT
- sRGB No Before PLTE and IDAT. If the sRGB chunk is present, the iCCP chunk should not be present.
- bKGD No After PLTE; before IDAT
- hIST No After PLTE; before IDAT
- tRNS No After PLTE; before IDAT
- pHYs No Before IDAT
- sPLT Yes Before IDAT
- tIME No None
- iTXt Yes None
- tEXt Yes None
- zTXt Yes None
+ * Ancillary chunks (need not appear in this order) Chunk name Multiple
+ * allowed Ordering constraints cHRM No Before PLTE and IDAT gAMA No
+ * Before PLTE and IDAT iCCP No Before PLTE and IDAT. If the iCCP chunk
+ * is present, the sRGB chunk should not be present. sBIT No Before PLTE
+ * and IDAT sRGB No Before PLTE and IDAT. If the sRGB chunk is present,
+ * the iCCP chunk should not be present. bKGD No After PLTE; before IDAT
+ * hIST No After PLTE; before IDAT tRNS No After PLTE; before IDAT pHYs
+ * No Before IDAT sPLT Yes Before IDAT tIME No None iTXt Yes None tEXt
+ * Yes None zTXt Yes None
*/
os.close();