123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- /* ====================================================================
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ==================================================================== */
-
- package org.apache.poi.hslf.record;
-
- import static org.apache.poi.util.GenericRecordUtil.getBitsAsString;
-
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.Arrays;
- import java.util.Map;
- import java.util.function.Supplier;
-
- import org.apache.poi.util.GenericRecordUtil;
- import org.apache.poi.util.LittleEndian;
- import org.apache.poi.util.LittleEndianConsts;
-
- /**
- * A SlideShowSlideInfo Atom (type 1017).<br>
- * <br>
- *
- * An atom record that specifies which transition effects to perform
- * during a slide show, and how to advance to the next presentation slide.<br>
- * <br>
- *
- * Combination of effectType and effectDirection:
- * <table>
- * <caption>Combination of effectType and effectDirection</caption>
- * <tr><th>type</th><th>description</th><th>direction</th></tr>
- * <tr><td>0</td><td>cut</td><td>0x00 = no transition, 0x01 = black transition</td></tr>
- * <tr><td>1</td><td>random</td><td>0x00</td></tr>
- * <tr><td>2</td><td>blinds</td><td>0x00 = vertical, 0x01 = horizontal</td></tr>
- * <tr><td>3</td><td>checker</td><td>like blinds</td></tr>
- * <tr><td>4</td><td>cover</td><td>0x00 = left, 0x01 = up, 0x02 = right, 0x03 = down, 0x04 = left/up, 0x05 = right/up, 0x06 left/down, 0x07 = left/down</td></tr>
- * <tr><td>5</td><td>dissolve</td><td>0x00</td></tr>
- * <tr><td>6</td><td>fade</td><td>0x00</td></tr>
- * <tr><td>7</td><td>uncover</td><td>like cover</td></tr>
- * <tr><td>8</td><td>random bars</td><td>like blinds</td></tr>
- * <tr><td>9</td><td>strips</td><td>like 0x04 - 0x07 of cover</td></tr>
- * <tr><td>10</td><td>wipe</td><td>like 0x00 - 0x03 of cover</td></tr>
- * <tr><td>11</td><td>box in/out</td><td>0x00 = out, 0x01 = in</td></tr>
- * <tr><td>13</td><td>split</td><td>0x00 = horizontally out, 0x01 = horizontally in, 0x02 = vertically out, 0x03 = vertically in</td></tr>
- * <tr><td>17</td><td>diamond</td><td>0x00</td></tr>
- * <tr><td>18</td><td>plus</td><td>0x00</td></tr>
- * <tr><td>19</td><td>wedge</td><td>0x00</td></tr>
- * <tr><td>20</td><td>push</td><td>like 0x00 - 0x03 of cover</td></tr>
- * <tr><td>21</td><td>comb</td><td>like blinds</td></tr>
- * <tr><td>22</td><td>newsflash</td><td>0x00</td></tr>
- * <tr><td>23</td><td>alphafade</td><td>0x00</td></tr>
- * <tr><td>26</td><td>wheel</td><td>number of radial divisions (0x01,0x02,0x03,0x04,0x08)</td></tr>
- * <tr><td>27</td><td>circle</td><td>0x00</td></tr>
- * <tr><td>255</td><td>undefined</td><td>0x00</td></tr>
- * </table>
- */
- public class SSSlideInfoAtom extends RecordAtom {
- /**
- * A bit that specifies whether the presentation slide can be
- * manually advanced by the user during the slide show.
- */
- public static final int MANUAL_ADVANCE_BIT = 1 << 0;
-
- /**
- * A bit that specifies whether the corresponding slide is
- * hidden and is not displayed during the slide show.
- */
- public static final int HIDDEN_BIT = 1 << 2;
-
- /**
- * A bit that specifies whether to play the sound specified by soundIfRef.
- */
- public static final int SOUND_BIT = 1 << 4;
-
- /**
- * A bit that specifies whether the sound specified by soundIdRef is
- * looped continuously when playing until the next sound plays.
- */
- public static final int LOOP_SOUND_BIT = 1 << 6;
-
- /**
- * A bit that specifies whether to stop any currently playing
- * sound when the transition starts.
- */
- public static final int STOP_SOUND_BIT = 1 << 8;
-
- /**
- * A bit that specifies whether the slide will automatically
- * advance after slideTime milliseconds during the slide show.
- */
- public static final int AUTO_ADVANCE_BIT = 1 << 10;
-
- /**
- * A bit that specifies whether to display the cursor during
- * the slide show.
- */
- public static final int CURSOR_VISIBLE_BIT = 1 << 12;
-
- // public static int RESERVED1_BIT = 1 << 1;
- // public static int RESERVED2_BIT = 1 << 3;
- // public static int RESERVED3_BIT = 1 << 5;
- // public static int RESERVED4_BIT = 1 << 7;
- // public static int RESERVED5_BIT = 1 << 9;
- // public static int RESERVED6_BIT = 1 << 11;
- // public static int RESERVED7_BIT = 1 << 13 | 1 << 14 | 1 << 15;
-
- private static final int[] EFFECT_MASKS = {
- MANUAL_ADVANCE_BIT,
- HIDDEN_BIT,
- SOUND_BIT,
- LOOP_SOUND_BIT,
- STOP_SOUND_BIT,
- AUTO_ADVANCE_BIT,
- CURSOR_VISIBLE_BIT
- };
-
- private static final String[] EFFECT_NAMES = {
- "MANUAL_ADVANCE",
- "HIDDEN",
- "SOUND",
- "LOOP_SOUND",
- "STOP_SOUND",
- "AUTO_ADVANCE",
- "CURSOR_VISIBLE"
- };
-
- private static final long _type = RecordTypes.SSSlideInfoAtom.typeID;
-
- private final byte[] _header;
-
- /**
- * A signed integer that specifies an amount of time, in milliseconds, to wait
- * before advancing to the next presentation slide. It MUST be greater than or equal to 0 and
- * less than or equal to 86399000. It MUST be ignored unless AUTO_ADVANCE_BIT is TRUE.
- */
- private int _slideTime;
-
- /**
- * A SoundIdRef that specifies which sound to play when the transition starts.
- */
- private int _soundIdRef;
-
- /**
- * A byte that specifies the variant of effectType. In combination of the effectType
- * there are further restriction and specification of this field.
- */
- private short _effectDirection; // byte
-
- /**
- * A byte that specifies which transition is used when transitioning to the
- * next presentation slide during a slide show. Exact rendering of any transition is
- * determined by the rendering application. As such, the same transition can have
- * many variations depending on the implementation.
- */
- private short _effectType; // byte
-
- /**
- * Various flags - see bitmask for more details
- */
- private short _effectTransitionFlags;
-
- /**
- * A byte value that specifies how long the transition takes to run.
- * (0x00 = 0.75 seconds, 0x01 = 0.5 seconds, 0x02 = 0.25 seconds)
- */
- private short _speed; // byte
- private final byte[] _unused; // 3-byte
-
- public SSSlideInfoAtom() {
- _header = new byte[8];
- LittleEndian.putShort(_header, 0, (short)0);
- LittleEndian.putShort(_header, 2, (short)_type);
- LittleEndian.putShort(_header, 4, (short)0x10);
- LittleEndian.putShort(_header, 6, (short)0);
- _unused = new byte[3];
- }
-
- public SSSlideInfoAtom(byte[] source, int offset, int len) {
- int ofs = offset;
-
- // Sanity Checking
- if(len != 24) len = 24;
-
- if (source.length < offset+len) {
- throw new IllegalArgumentException("Need at least " + (offset + len) +
- " bytes with offset " + offset + ", length " + len + " and array-size " + source.length);
- }
-
- // Get the header
- _header = Arrays.copyOfRange(source, ofs, ofs+8);
- ofs += _header.length;
-
- if (LittleEndian.getShort(_header, 0) != 0) {
- LOG.debug("Invalid data for SSSlideInfoAtom at offset 0: {}", LittleEndian.getShort(_header, 0));
- }
- if (LittleEndian.getShort(_header, 2) != RecordTypes.SSSlideInfoAtom.typeID) {
- LOG.debug("Invalid data for SSSlideInfoAtom at offset 2: {}", LittleEndian.getShort(_header, 2));
- }
- if (LittleEndian.getShort(_header, 4) != 0x10) {
- LOG.debug("Invalid data for SSSlideInfoAtom at offset 4: {}", LittleEndian.getShort(_header, 4));
- }
- if (LittleEndian.getShort(_header, 6) == 0) {
- LOG.debug("Invalid data for SSSlideInfoAtom at offset 6: {}", LittleEndian.getShort(_header, 6));
- }
-
- _slideTime = LittleEndian.getInt(source, ofs);
- if (_slideTime < 0 || _slideTime > 86399000) {
- LOG.debug("Invalid data for SSSlideInfoAtom - invalid slideTime: {}", _slideTime);
- }
- ofs += LittleEndianConsts.INT_SIZE;
- _soundIdRef = LittleEndian.getInt(source, ofs);
- ofs += LittleEndianConsts.INT_SIZE;
- _effectDirection = LittleEndian.getUByte(source, ofs);
- ofs += LittleEndianConsts.BYTE_SIZE;
- _effectType = LittleEndian.getUByte(source, ofs);
- ofs += LittleEndianConsts.BYTE_SIZE;
- _effectTransitionFlags = LittleEndian.getShort(source, ofs);
- ofs += LittleEndianConsts.SHORT_SIZE;
- _speed = LittleEndian.getUByte(source, ofs);
- ofs += LittleEndianConsts.BYTE_SIZE;
- _unused = Arrays.copyOfRange(source, ofs,ofs+3);
- }
-
- /**
- * Write the contents of the record back, so it can be written
- * to disk
- */
- @Override
- public void writeOut(OutputStream out) throws IOException {
- // Header - size or type unchanged
- out.write(_header);
- writeLittleEndian(_slideTime, out);
- writeLittleEndian(_soundIdRef, out);
-
- byte[] byteBuf = new byte[LittleEndianConsts.BYTE_SIZE];
- LittleEndian.putUByte(byteBuf, 0, _effectDirection);
- out.write(byteBuf);
- LittleEndian.putUByte(byteBuf, 0, _effectType);
- out.write(byteBuf);
-
- writeLittleEndian(_effectTransitionFlags, out);
- LittleEndian.putUByte(byteBuf, 0, _speed);
- out.write(byteBuf);
-
- assert(_unused.length == 3);
- out.write(_unused);
- }
-
- /**
- * We are of type 1017
- */
- @Override
- public long getRecordType() { return _type; }
-
-
- public int getSlideTime() {
- return _slideTime;
- }
-
- public void setSlideTime(int slideTime) {
- this._slideTime = slideTime;
- }
-
- public int getSoundIdRef() {
- return _soundIdRef;
- }
-
- public void setSoundIdRef(int soundIdRef) {
- this._soundIdRef = soundIdRef;
- }
-
- public short getEffectDirection() {
- return _effectDirection;
- }
-
- public void setEffectDirection(short effectDirection) {
- this._effectDirection = effectDirection;
- }
-
- public short getEffectType() {
- return _effectType;
- }
-
- public void setEffectType(short effectType) {
- this._effectType = effectType;
- }
-
- public short getEffectTransitionFlags() {
- return _effectTransitionFlags;
- }
-
- public void setEffectTransitionFlags(short effectTransitionFlags) {
- this._effectTransitionFlags = effectTransitionFlags;
- }
-
- /**
- * Use one of the bitmasks MANUAL_ADVANCE_BIT ... CURSOR_VISIBLE_BIT
- */
- public void setEffectTransitionFlagByBit(int bitmask, boolean enabled) {
- if (enabled) {
- _effectTransitionFlags |= bitmask;
- } else {
- _effectTransitionFlags &= (0xFFFF ^ bitmask);
- }
- }
-
- public boolean getEffectTransitionFlagByBit(int bitmask) {
- return ((_effectTransitionFlags & bitmask) != 0);
- }
-
- public short getSpeed() {
- return _speed;
- }
-
- public void setSpeed(short speed) {
- this._speed = speed;
- }
-
- @Override
- public Map<String, Supplier<?>> getGenericProperties() {
- return GenericRecordUtil.getGenericProperties(
- "effectTransitionFlags", getBitsAsString(this::getEffectTransitionFlags, EFFECT_MASKS, EFFECT_NAMES),
- "slideTime", this::getSlideTime,
- "soundIdRef", this::getSoundIdRef,
- "effectDirection", this::getEffectDirection,
- "effectType", this::getEffectType,
- "speed", this::getSpeed
- );
- }
- }
|