1 package com.keypoint; 2 3 39 40 import java.awt.image.BufferedImage ; 41 import java.awt.image.DataBuffer ; 42 import java.awt.image.IndexColorModel ; 43 import java.awt.image.WritableRaster ; 44 import java.io.ByteArrayOutputStream ; 45 import java.io.IOException ; 46 import java.util.zip.Deflater ; 47 import java.util.zip.DeflaterOutputStream ; 48 49 public class PngEncoderB extends PngEncoder { 50 protected BufferedImage image; 51 protected WritableRaster wRaster; 52 protected int tType; 53 54 57 public PngEncoderB() { 58 this(null, false, FILTER_NONE, 0); 59 } 60 61 66 public PngEncoderB(BufferedImage image) { 67 this(image, false, FILTER_NONE, 0); 68 } 69 70 76 public PngEncoderB(BufferedImage image, boolean encodeAlpha) { 77 this(image, encodeAlpha, FILTER_NONE, 0); 78 } 79 80 87 public PngEncoderB(BufferedImage image, boolean encodeAlpha, 88 int whichFilter) { 89 this(image, encodeAlpha, whichFilter, 0); 90 } 91 92 100 public PngEncoderB(BufferedImage image, boolean encodeAlpha, 101 int whichFilter, int compLevel) { 102 this.image = image; 103 this.encodeAlpha = encodeAlpha; 104 setFilter(whichFilter); 105 if (compLevel >= 0 && compLevel <= 9) { 106 this.compressionLevel = compLevel; 107 } 108 } 109 110 115 public void setImage(BufferedImage image) { 116 this.image = image; 117 pngBytes = null; 118 } 119 120 126 public byte[] pngEncode(boolean encodeAlpha) { 127 byte[] pngIdBytes = {-119, 80, 78, 71, 13, 10, 26, 10}; 128 int i; 129 130 if (image == null) { 131 return null; 132 } 133 width = image.getWidth(null); 134 height = image.getHeight(null); 135 137 if (!establishStorageInfo()) { 138 return null; 139 } 140 141 145 pngBytes = new byte[((width + 1) * height * 3) + 200]; 146 147 150 maxPos = 0; 151 152 bytePos = writeBytes(pngIdBytes, 0); 153 hdrPos = bytePos; 154 writeHeader(); 155 dataPos = bytePos; 156 if (writeImageData()) { 157 writeEnd(); 158 pngBytes = resizeByteArray(pngBytes, maxPos); 159 } else { 160 pngBytes = null; 161 } 162 return pngBytes; 163 } 164 165 171 public byte[] pngEncode() { 172 return pngEncode(encodeAlpha); 173 } 174 175 186 protected boolean establishStorageInfo() { 187 int dataBytes; 188 189 wRaster = image.getRaster(); 190 dataBytes = wRaster.getNumDataElements(); 191 tType = wRaster.getTransferType(); 192 193 if (((tType == DataBuffer.TYPE_BYTE) && (dataBytes == 4)) || 194 ((tType == DataBuffer.TYPE_INT) && (dataBytes == 1))) { 195 bytesPerPixel = (encodeAlpha) ? 4 : 3; 196 } else if ((tType == DataBuffer.TYPE_BYTE) && (dataBytes == 1)) { 197 bytesPerPixel = 1; 198 encodeAlpha = false; } else { 200 return false; 201 } 202 return true; 203 } 204 205 208 protected void writeHeader() { 209 int startPos; 210 211 startPos = bytePos = writeInt4(13, bytePos); 212 bytePos = writeString("IHDR", bytePos); 213 width = image.getWidth(null); 214 height = image.getHeight(null); 215 bytePos = writeInt4(width, bytePos); 216 bytePos = writeInt4(height, bytePos); 217 bytePos = writeByte(8, bytePos); if (bytesPerPixel != 1) { 219 bytePos = writeByte((encodeAlpha) ? 6 : 2, bytePos); } else { 221 bytePos = writeByte(3, bytePos); } 223 bytePos = writeByte(0, bytePos); bytePos = writeByte(0, bytePos); bytePos = writeByte(0, bytePos); crc.reset(); 227 crc.update(pngBytes, startPos, bytePos - startPos); 228 crcValue = crc.getValue(); 229 bytePos = writeInt4((int) crcValue, bytePos); 230 } 231 232 protected void writePalette(IndexColorModel icm) { 233 byte[] redPal = new byte[256]; 234 byte[] greenPal = new byte[256]; 235 byte[] bluePal = new byte[256]; 236 byte[] allPal = new byte[768]; 237 int i; 238 239 icm.getReds(redPal); 240 icm.getGreens(greenPal); 241 icm.getBlues(bluePal); 242 for (i = 0; i < 256; i++) { 243 allPal[i * 3] = redPal[i]; 244 allPal[i * 3 + 1] = greenPal[i]; 245 allPal[i * 3 + 2] = bluePal[i]; 246 } 247 bytePos = writeInt4(768, bytePos); 248 bytePos = writeString("PLTE", bytePos); 249 crc.reset(); 250 crc.update("PLTE".getBytes()); 251 bytePos = writeBytes(allPal, bytePos); 252 crc.update(allPal); 253 crcValue = crc.getValue(); 254 bytePos = writeInt4((int) crcValue, bytePos); 255 } 256 257 265 protected boolean writeImageData() { 266 int rowsLeft = height; int startRow = 0; int nRows; 270 byte[] scanLines; int scanPos; int startPos; int readPos; 275 byte[] compressedLines; int nCompressed; 278 byte[] pixels; int[] iPixels; 281 Deflater scrunch = new Deflater (compressionLevel); 282 ByteArrayOutputStream outBytes = 283 new ByteArrayOutputStream (1024); 284 285 DeflaterOutputStream compBytes = 286 new DeflaterOutputStream (outBytes, scrunch); 287 288 if (bytesPerPixel == 1) { 289 writePalette((IndexColorModel ) image.getColorModel()); 290 } 291 292 try { 293 while (rowsLeft > 0) { 294 nRows = Math.min(32767 / (width * (bytesPerPixel + 1)), rowsLeft); 295 297 301 scanLines = new byte[width * nRows * bytesPerPixel + nRows]; 302 303 if (filter == FILTER_SUB) { 304 leftBytes = new byte[16]; 305 } 306 if (filter == FILTER_UP) { 307 priorRow = new byte[width * bytesPerPixel]; 308 } 309 310 if (tType == DataBuffer.TYPE_BYTE) { 311 pixels = (byte[]) wRaster.getDataElements(0, startRow, width, nRows, null); 312 iPixels = null; 313 } else { 314 iPixels = (int[]) wRaster.getDataElements(0, startRow, width, nRows, null); 315 pixels = null; 316 } 317 318 scanPos = 0; 319 readPos = 0; 320 startPos = 1; 321 for (int i = 0; i < width * nRows; i++) { 322 if (i % width == 0) { 323 scanLines[scanPos++] = (byte) filter; 324 startPos = scanPos; 325 } 326 327 if (bytesPerPixel == 1) { 328 scanLines[scanPos++] = pixels[readPos++]; 329 } else if (tType == DataBuffer.TYPE_BYTE) { 330 scanLines[scanPos++] = pixels[readPos++]; 331 scanLines[scanPos++] = pixels[readPos++]; 332 scanLines[scanPos++] = pixels[readPos++]; 333 if (encodeAlpha) { 334 scanLines[scanPos++] = pixels[readPos++]; 335 } else { 336 readPos++; 337 } 338 } else { 339 scanLines[scanPos++] = (byte) ((iPixels[readPos] >> 16) & 0xff); 340 scanLines[scanPos++] = (byte) ((iPixels[readPos] >> 8) & 0xff); 341 scanLines[scanPos++] = (byte) ((iPixels[readPos]) & 0xff); 342 if (encodeAlpha) { 343 scanLines[scanPos++] = (byte) ((iPixels[readPos] >> 24) & 0xff); 344 } 345 readPos++; 346 } 347 if ((i % width == width - 1) && (filter != FILTER_NONE)) { 348 if (filter == FILTER_SUB) { 349 filterSub(scanLines, startPos, width); 350 } 351 if (filter == FILTER_UP) { 352 filterUp(scanLines, startPos, width); 353 } 354 } 355 } 356 357 360 compBytes.write(scanLines, 0, scanPos); 361 362 startRow += nRows; 363 rowsLeft -= nRows; 364 } 365 compBytes.close(); 366 367 370 compressedLines = outBytes.toByteArray(); 371 nCompressed = compressedLines.length; 372 373 crc.reset(); 374 bytePos = writeInt4(nCompressed, bytePos); 375 bytePos = writeString("IDAT", bytePos); 376 crc.update("IDAT".getBytes()); 377 bytePos = writeBytes(compressedLines, nCompressed, bytePos); 378 crc.update(compressedLines, 0, nCompressed); 379 380 crcValue = crc.getValue(); 381 bytePos = writeInt4((int) crcValue, bytePos); 382 scrunch.finish(); 383 return true; 384 } catch (IOException e) { 385 System.err.println(e.toString()); 386 return false; 387 } 388 } 389 390 } 391 392 | Popular Tags |