1 29 30 package com.caucho.quercus.lib.pdf; 31 32 import com.caucho.util.L10N; 33 import com.caucho.vfs.Path; 34 import com.caucho.vfs.ReadStream; 35 import com.caucho.vfs.TempBuffer; 36 import com.caucho.vfs.TempStream; 37 import com.caucho.vfs.WriteStream; 38 39 import java.io.IOException ; 40 import java.util.logging.Logger ; 41 42 45 public class PDFImage extends PDFObject { 46 private static final Logger log 47 = Logger.getLogger(PDFImage.class.getName()); 48 private static final L10N L = new L10N(PDFImage.class); 49 50 private ReadStream _is; 51 52 private int _id; 53 54 private String _type; 55 private int _width; 56 private int _height; 57 private int _bits; 58 private TempBuffer _jpegHead; 59 60 public PDFImage(Path path) 61 throws IOException 62 { 63 _is = path.openRead(); 64 65 try { 66 parseImage(); 67 } finally { 68 _is.close(); 69 } 70 } 71 72 75 public int getId() 76 { 77 return _id; 78 } 79 80 83 public void setId(int id) 84 { 85 _id = id; 86 } 87 88 public double get_width() 89 { 90 return _width; 91 } 92 93 public double get_height() 94 { 95 return _height; 96 } 97 98 private boolean parseImage() 99 throws IOException 100 { 101 int ch = _is.read(); 102 103 if (ch == 'G') { 104 if (_is.read() != 'I' || 105 _is.read() != 'F' || 106 _is.read() != '8' || 107 _is.read() != '7' || 108 _is.read() != 'a') 109 return false; 110 111 return parseGIF(); 112 } 113 else if (ch == 0xff) { 114 if (_is.read() != 0xd8) 115 return false; 116 117 TempStream ts = new TempStream(); 118 119 WriteStream ws = new WriteStream(ts); 120 ws.write(0xff); 121 ws.write(0xd8); 122 _is.writeToStream(ws); 123 ws.close(); 124 125 _jpegHead = ts.getHead(); 126 _is.close(); 127 128 _is = new ReadStream(); 129 ts.openRead(_is); 130 131 parseJPEG(); 132 133 return true; 134 } 135 136 return false; 137 } 138 139 private boolean parseGIF() 140 throws IOException 141 { 142 int width = (_is.read() & 0xff) + 256 * (_is.read() & 0xff); 143 int heigth = (_is.read() & 0xff) + 256 * (_is.read() & 0xff); 144 int flags = _is.read(); 145 int background = _is.read(); 146 int pad = _is.read(); 147 148 int depth = (flags & 0x7) + 1; 149 150 int []colorMap = null; 151 152 if ((flags & 0x80) != 0) { 153 colorMap = parseGIFColorMap(depth); 154 } 155 else { 156 System.out.println("GIF: can't cope with local"); 157 return false; 158 } 159 160 int ch = _is.read(); 161 if (ch != ',') 162 return false; 163 164 int imgLeft = (_is.read() & 0xff) + 256 * (_is.read() & 0xff); 165 int imgTop = (_is.read() & 0xff) + 256 * (_is.read() & 0xff); 166 int imgWidth = (_is.read() & 0xff) + 256 * (_is.read() & 0xff); 167 int imgHeight = (_is.read() & 0xff) + 256 * (_is.read() & 0xff); 168 flags = _is.read() & 0xff; 169 170 if ((flags & 0x80) != 0) { 171 System.out.println("GIF: can't cope with local"); 172 return false; 173 } 174 if ((flags & 0x40) != 0) { 175 System.out.println("GIF: can't cope with interlaced"); 176 return false; 177 } 178 179 parseGIFData(colorMap); 180 181 return false; 182 } 183 184 private int []parseGIFColorMap(int depth) 185 throws IOException 186 { 187 int []values = new int[1 << depth]; 188 189 for (int i = 0; i < values.length; i++) { 190 int value = (0x10000 * (_is.read() & 0xff) + 191 0x100 * (_is.read() & 0xff) + 192 0x1 * (_is.read() & 0xff)); 193 194 values[i] = value; 195 } 196 197 return values; 198 } 199 200 private void parseGIFData(int []colorMap) 201 throws IOException 202 { 203 225 } 226 227 private boolean parseJPEG() 228 throws IOException 229 { 230 if (_is.read() != 0xff || 231 _is.read() != 0xd8) 232 return false; 233 234 int ch; 235 236 while ((ch = _is.read()) == 0xff) { 237 ch = _is.read(); 238 239 if (ch == 0xff) { 240 _is.unread(); 241 } 242 else if (0xd0 <= ch && ch <= 0xd9) { 243 } 245 else if (0x01 == ch) { 246 } 248 else if (ch == 0xc0) { 249 int len = 256 * _is.read() + _is.read(); 250 251 _bits = _is.read(); 252 _height = 256 * _is.read() + _is.read(); 253 _width = 256 * _is.read() + _is.read(); 254 _type = "jpeg"; 255 256 return true; 257 } 258 else { 259 int len = 256 * _is.read() + _is.read(); 260 261 _is.skip(len - 2); 262 } 263 } 264 265 return false; 266 } 267 268 String getResource() 269 { 270 return ("/XObject << /I" + _id + " " + _id + " 0 R >>"); 271 } 272 273 276 public void writeObject(PDFWriter out) 277 throws IOException 278 { 279 int length = 0; 280 281 for (TempBuffer ptr = _jpegHead; ptr != null; ptr = ptr.getNext()) 282 length += ptr.getLength(); 283 284 out.println("<< /Type /XObject"); 285 out.println(" /Subtype /Image"); 286 out.println(" /Width " + _width); 287 out.println(" /Height " + _height); 288 out.println(" /ColorSpace /DeviceRGB"); 289 out.println(" /BitsPerComponent " + _bits); 290 out.println(" /Filter /DCTDecode"); 291 out.println(" /Length " + length); 292 out.println(">>"); 293 out.println("stream"); 294 295 for (TempBuffer ptr = _jpegHead; ptr != null; ptr = ptr.getNext()) { 296 out.write(ptr.getBuffer(), 0, ptr.getLength()); 297 } 298 out.println(); 299 out.println("endstream"); 300 } 301 302 static class GIFDecode { 303 private final int _codeSize; 304 private final int _clearCode; 305 private final int _endOfCode; 306 307 private ReadStream _is; 308 private int _blockSize; 309 310 GIFDecode(ReadStream is) 311 throws IOException 312 { 313 _is = is; 314 315 _codeSize = _is.read(); 316 _clearCode = 1 << _codeSize; 317 _endOfCode = _clearCode + 1; 318 } 319 320 int readByte() 321 throws IOException 322 { 323 if (_blockSize < 0) 324 return -1; 325 else if (_blockSize == 0) { 326 _blockSize = _is.read(); 327 328 if (_blockSize == 0) { 329 _blockSize = -1; 330 return -1; 331 } 332 } 333 334 _blockSize--; 335 336 return _is.read(); 337 } 338 } 339 } 340 | Popular Tags |