1 20 package gnu.jpdf; 21 22 import java.awt.Image ; 23 import java.awt.image.*; 24 import java.io.*; 25 import java.util.*; 26 import java.util.zip.*; 27 28 39 public class PDFImage extends PDFStream implements ImageObserver, Serializable 40 { 41 52 53 54 private int objwidth; 56 private int objheight; 57 58 private int width; 60 private int height; 61 private Image img; 62 private String name; 63 64 65 69 public PDFImage() 70 { 71 super("/XObject"); 72 } 73 74 79 public PDFImage(Image img) { 80 this(); 81 setImage(img, 0, 0, img.getWidth(this), img.getHeight(this), this); 82 } 83 84 94 public PDFImage(Image img,int x,int y,int w,int h,ImageObserver obs) { 95 this(); 96 objwidth = w; 97 objheight = h; 98 setImage(img, x, y, img.getWidth(this), img.getHeight(this), obs); 99 } 100 101 102 106 public int getWidth() { 107 return width; 108 } 109 110 114 public void setWidth(int v) { 115 this.width = v; 116 } 117 118 122 public int getHeight() { 123 return height; 124 } 125 126 130 public void setHeight(int v) { 131 this.height = v; 132 } 133 134 135 140 public void setName(String n) { 141 name = n; 142 } 143 144 149 public String getName() { 150 return name; 151 } 152 153 163 public void setImage(Image img,int x,int y,int w,int h,ImageObserver obs) { 164 this.img = img; 165 width = w; 166 height = h; 167 } 168 169 170 171 181 private String base85Encoding(String stringToEncode) 182 throws NumberFormatException { 183 if ((stringToEncode == null) || (stringToEncode.length() == 0)) { 184 return ""; 186 } 187 if ((stringToEncode.length() > 8) || 188 ((stringToEncode.length() % 2) != 0)) { 189 System.out.println("PDFImage.base85Encoding, Incorrect tuple length: " + 190 stringToEncode.length()); 191 return ""; 192 } 193 StringBuffer sb = new StringBuffer (); 196 197 206 int numHexDigits = stringToEncode.length() / 2; 207 int numAppendBytes = 4 - numHexDigits; 208 for (int i = 0; i < numAppendBytes; i++) { 209 stringToEncode += "00"; 210 } 211 Vector digitVector = new Vector(); 212 long number = Long.parseLong(stringToEncode, 16); 213 int remainder = 0; 214 215 while (number >= 85) { 216 remainder = (int) (number % 85); 217 number = number / 85; 218 digitVector.add( 0, new Integer ( remainder ) ); 219 } 220 digitVector.add( 0, new Integer ( (int)number ) ); 221 222 for ( int i = 0; i < digitVector.size(); i++) { 223 char c = (char) (((Integer )digitVector.elementAt(i)).intValue() + 33); 224 sb.append(c); 225 } 226 String tuple = sb.toString(); 227 int len = tuple.length(); 228 switch (len) { 229 case 1: tuple = "!!!!" + tuple; break; 230 case 2: tuple = "!!!" + tuple; break; 231 case 3: tuple = "!!" + tuple; break; 232 case 4: tuple = "!" + tuple; break; 233 default: break; 234 } 237 return (tuple); 238 } 240 241 242 248 public void writeStream(OutputStream os) throws IOException { 249 259 ByteArrayOutputStream b = new ByteArrayOutputStream(); 260 DeflaterOutputStream dos = new DeflaterOutputStream(b); 261 buf.writeTo(dos); 262 dos.finish(); 263 dos.close(); 264 265 os.write("/Filter [/FlateDecode /ASCII85Decode]\n".getBytes()); 268 os.write("/Length ".getBytes()); 269 os.write(Integer.toString(b.size()).getBytes()); 270 os.write("\n>>\nstream\n".getBytes()); 271 b.writeTo(os); 272 os.write("\nendstream\nendobj\n".getBytes()); 273 274 } 276 277 283 public void write(OutputStream os) throws IOException 284 { 285 writeStart(os); 286 287 os.write("/Subtype /Image\n/Name ".getBytes()); 289 os.write(name.getBytes()); 290 os.write("\n/Width ".getBytes()); 291 os.write(Integer.toString(width).getBytes()); 292 os.write("\n/Height ".getBytes()); 293 os.write(Integer.toString(height).getBytes()); 294 os.write("\n/BitsPerComponent 8\n/ColorSpace /DeviceRGB\n".getBytes()); 295 296 ByteArrayOutputStream bos = getStream(); 299 300 int w = width; 301 int h = height; 302 int x = 0; 303 int y = 0; 304 int[] pixels = new int[w * h]; 305 PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w); 306 try { 307 pg.grabPixels(); 308 } catch (InterruptedException e) { 309 System.err.println("interrupted waiting for pixels!"); 310 return; 311 } 312 if ((pg.getStatus() & ImageObserver.ABORT) != 0) { 313 System.err.println("image fetch aborted or errored"); 314 return; 315 } 316 StringBuffer out = new StringBuffer (); 317 for (int j = 0; j < h; j++) { 318 for (int i = 0; i < w; i++) { 319 out.append(handlePixel(x+i, y+j, pixels[j * w + i])); 321 if (out.toString().length() >= 8) { 322 String tuple = out.substring(0, 8); 323 out.delete(0, 8); 324 String encTuple = base85Encoding(tuple); 326 if (encTuple.equals("!!!!!")) { 327 encTuple = "z"; 328 } 329 bos.write(encTuple.getBytes()); 330 } 331 } 332 } 333 335 String lastTuple = base85Encoding(out.toString()); 336 bos.write(lastTuple.getBytes()); 338 bos.write("~".getBytes()); 339 340 341 343 setDeflate(false); 345 346 writeStream(os); 347 348 } 350 351 352 353 361 public static String handlePixel(int x, int y, int p) { 362 int alpha = (p >> 24) & 0xff; 363 int red = (p >> 16) & 0xff; 364 int green = (p >> 8) & 0xff; 365 int blue = (p ) & 0xff; 366 String redHex = Integer.toHexString(red); 367 String greenHex = Integer.toHexString(green); 368 String blueHex = Integer.toHexString(blue); 369 if (redHex.length() == 1) { 370 redHex = "0" + redHex; 371 } 372 if (greenHex.length() == 1) { 373 greenHex = "0" + greenHex; 374 } 375 if (blueHex.length() == 1) { 376 blueHex = "0" + blueHex; 377 } 378 return redHex + greenHex + blueHex; 379 } 381 382 383 384 385 396 public boolean imageUpdate(Image img,int infoflags,int x,int y,int w,int h) { 397 System.err.println("img="+img+"\ninfoflags="+infoflags+ 398 "\nx="+x+" y="+y+" w="+w+" h="+h); 399 if(infoflags==ImageObserver.WIDTH) 401 width = w; 402 if(infoflags==ImageObserver.HEIGHT) 403 height = h; 404 405 return false; 408 } 409 410 } | Popular Tags |