📄 hslfslideshow.java
字号:
private void readOtherStreams() { // Currently, there aren't any } /** * Find and read in pictures contained in this presentation */ private void readPictures() throws IOException { byte[] pictstream; try { DocumentEntry entry = (DocumentEntry)filesystem.getRoot().getEntry("Pictures"); pictstream = new byte[entry.getSize()]; DocumentInputStream is = filesystem.createDocumentInputStream("Pictures"); is.read(pictstream); } catch (FileNotFoundException e){ // Silently catch exceptions if the presentation doesn't // contain pictures - will use a null set instead return; } List p = new ArrayList(); int pos = 0; // An empty picture record (length 0) will take up 8 bytes while (pos <= (pictstream.length-8)) { int offset = pos; // Image signature int signature = LittleEndian.getUShort(pictstream, pos); pos += LittleEndian.SHORT_SIZE; // Image type + 0xF018 int type = LittleEndian.getUShort(pictstream, pos); pos += LittleEndian.SHORT_SIZE; // Image size (excluding the 8 byte header) int imgsize = LittleEndian.getInt(pictstream, pos); pos += LittleEndian.INT_SIZE; // The image size must be 0 or greater // (0 is allowed, but odd, since we do wind on by the header each // time, so we won't get stuck) if(imgsize < 0) { throw new CorruptPowerPointFileException("The file contains a picture, at position " + p.size() + ", which has a negatively sized data length, so we can't trust any of the picture data"); } // If they type (including the bonus 0xF018) is 0, skip it if(type == 0) { logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!"); logger.log(POILogger.ERROR, "" + pos); } else { // Copy the data, ready to pass to PictureData byte[] imgdata = new byte[imgsize]; if(imgsize > 0) { System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length); } // Build the PictureData object from the data try { PictureData pict = PictureData.create(type - 0xF018); pict.setRawData(imgdata); pict.setOffset(offset); p.add(pict); } catch(IllegalArgumentException e) { logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!"); } } pos += imgsize; } _pictures = (PictureData[])p.toArray(new PictureData[p.size()]); } /** * Writes out the slideshow file the is represented by an instance * of this class. * It will write out the common OLE2 streams. If you require all * streams to be written out, pass in preserveNodes * @param out The OutputStream to write to. * @throws IOException If there is an unexpected IOException from * the passed in OutputStream */ public void write(OutputStream out) throws IOException { // Write out, but only the common streams write(out,false); } /** * Writes out the slideshow file the is represented by an instance * of this class. * If you require all streams to be written out (eg Marcos, embeded * documents), then set preserveNodes to true * @param out The OutputStream to write to. * @param preserveNodes Should all OLE2 streams be written back out, or only the common ones? * @throws IOException If there is an unexpected IOException from * the passed in OutputStream */ public void write(OutputStream out, boolean preserveNodes) throws IOException { // Get a new Filesystem to write into POIFSFileSystem outFS = new POIFSFileSystem(); // The list of entries we've written out List writtenEntries = new ArrayList(1); // Write out the Property Streams writeProperties(outFS, writtenEntries); // For position dependent records, hold where they were and now are // As we go along, update, and hand over, to any Position Dependent // records we happen across Hashtable oldToNewPositions = new Hashtable(); // First pass - figure out where all the position dependent // records are going to end up, in the new scheme // (Annoyingly, some powerpoing files have PersistPtrHolders // that reference slides after the PersistPtrHolder) ByteArrayOutputStream baos = new ByteArrayOutputStream(); for(int i=0; i<_records.length; i++) { if(_records[i] instanceof PositionDependentRecord) { PositionDependentRecord pdr = (PositionDependentRecord)_records[i]; int oldPos = pdr.getLastOnDiskOffset(); int newPos = baos.size(); pdr.setLastOnDiskOffset(newPos); oldToNewPositions.put(new Integer(oldPos),new Integer(newPos)); //System.out.println(oldPos + " -> " + newPos); } // Dummy write out, so the position winds on properly _records[i].writeOut(baos); } // No go back through, actually writing ourselves out baos.reset(); for(int i=0; i<_records.length; i++) { // For now, we're only handling PositionDependentRecord's that // happen at the top level. // In future, we'll need the handle them everywhere, but that's // a bit trickier if(_records[i] instanceof PositionDependentRecord) { // We've already figured out their new location, and // told them that // Tell them of the positions of the other records though PositionDependentRecord pdr = (PositionDependentRecord)_records[i]; pdr.updateOtherRecordReferences(oldToNewPositions); } // Whatever happens, write out that record tree _records[i].writeOut(baos); } // Update our cached copy of the bytes that make up the PPT stream _docstream = baos.toByteArray(); // Write the PPT stream into the POIFS layer ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); outFS.createDocument(bais,"PowerPoint Document"); writtenEntries.add("PowerPoint Document"); // Update and write out the Current User atom int oldLastUserEditAtomPos = (int)currentUser.getCurrentEditOffset(); Integer newLastUserEditAtomPos = (Integer)oldToNewPositions.get(new Integer(oldLastUserEditAtomPos)); if(newLastUserEditAtomPos == null) { throw new HSLFException("Couldn't find the new location of the UserEditAtom that used to be at " + oldLastUserEditAtomPos); } currentUser.setCurrentEditOffset(newLastUserEditAtomPos.intValue()); currentUser.writeToFS(outFS); writtenEntries.add("Current User"); // Write any pictures, into another stream if (_pictures != null) { ByteArrayOutputStream pict = new ByteArrayOutputStream(); for (int i = 0; i < _pictures.length; i++ ) { _pictures[i].write(pict); } outFS.createDocument( new ByteArrayInputStream(pict.toByteArray()), "Pictures" ); writtenEntries.add("Pictures"); } // If requested, write out any other streams we spot if(preserveNodes) { copyNodes(filesystem, outFS, writtenEntries); } // Send the POIFSFileSystem object out to the underlying stream outFS.writeFilesystem(out); } /* ******************* adding methods follow ********************* */ /** * Adds a new root level record, at the end, but before the last * PersistPtrIncrementalBlock. */ public synchronized int appendRootLevelRecord(Record newRecord) { int addedAt = -1; Record[] r = new Record[_records.length+1]; boolean added = false; for(int i=(_records.length-1); i>=0; i--) { if(added) { // Just copy over r[i] = _records[i]; } else { r[(i+1)] = _records[i]; if(_records[i] instanceof PersistPtrHolder) { r[i] = newRecord; added = true; addedAt = i; } } } _records = r; return addedAt; } /** * Add a new picture to this presentation. */ public void addPicture(PictureData img) { // Copy over the existing pictures, into an array one bigger PictureData[] lst; if(_pictures == null) { lst = new PictureData[1]; } else { lst = new PictureData[(_pictures.length+1)]; System.arraycopy(_pictures,0,lst,0,_pictures.length); } // Add in the new image lst[lst.length - 1] = img; _pictures = lst; } /* ******************* fetching methods follow ********************* */ /** * Returns an array of all the records found in the slideshow */ public Record[] getRecords() { return _records; } /** * Returns an array of the bytes of the file. Only correct after a * call to open or write - at all other times might be wrong! */ public byte[] getUnderlyingBytes() { return _docstream; } /** * Fetch the Current User Atom of the document */ public CurrentUserAtom getCurrentUserAtom() { return currentUser; } /** * Return array of pictures contained in this presentation * * @return array with the read pictures or <code>null</code> if the * presentation doesn't contain pictures. */ public PictureData[] getPictures() { return _pictures; } /** * Gets embedded object data from the slide show. * * @return the embedded objects. */ public ObjectData[] getEmbeddedObjects() { if (_objects == null) { List objects = new ArrayList(); for (int i = 0; i < _records.length; i++) { if (_records[i] instanceof ExOleObjStg) { objects.add(new ObjectData((ExOleObjStg) _records[i])); } } _objects = (ObjectData[]) objects.toArray(new ObjectData[objects.size()]); } return _objects; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -