View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.imaging.formats.webp.chunks;
18  
19  import java.io.IOException;
20  import java.io.PrintWriter;
21  
22  import org.apache.commons.imaging.ImagingException;
23  
24  /**
25   * VP8X (descriptions of features used) chunk.
26   *
27   * <pre>{@code
28   *  0                   1                   2                   3
29   *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
30   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31   * |                                                               |
32   * |                   WebP file header (12 bytes)                 |
33   * |                                                               |
34   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35   * |                      ChunkHeader('VP8X')                      |
36   * |                                                               |
37   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38   * |Rsv|I|L|E|X|A|R|                   Reserved                    |
39   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40   * |          Canvas Width Minus One               |             ...
41   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42   * ...  Canvas Height Minus One    |
43   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44   * }</pre>
45   *
46   * @see <a href="https://developers.google.com/speed/webp/docs/riff_container#extended_file_format">Extended File Format</a>
47   * @since 1.0-alpha4
48   */
49  public final class WebPChunkVp8x extends WebPChunk {
50      private final boolean hasIcc;
51      private final boolean hasAlpha;
52      private final boolean hasExif;
53      private final boolean hasXmp;
54      private final boolean hasAnimation;
55      private final int canvasWidth;
56      private final int canvasHeight;
57  
58      /**
59       * Create a VP8x chunk.
60       *
61       * @param type  VP8X chunk type
62       * @param size  VP8X chunk size
63       * @param bytes VP8X chunk data
64       * @throws ImagingException if the chunk data and the size provided do not match, or if the other parameters provided are invalid.
65       */
66      public WebPChunkVp8x(final int type, final int size, final byte[] bytes) throws ImagingException {
67          super(type, size, bytes);
68  
69          if (size != 10) {
70              throw new ImagingException("VP8X chunk size must be 10");
71          }
72  
73          final int mark = bytes[0] & 0xFF;
74          this.hasIcc = (mark & 0b0010_0000) != 0;
75          this.hasAlpha = (mark & 0b0001_0000) != 0;
76          this.hasExif = (mark & 0b0000_1000) != 0;
77          this.hasXmp = (mark & 0b0000_0100) != 0;
78          this.hasAnimation = (mark & 0b0000_0010) != 0;
79  
80          this.canvasWidth = (bytes[4] & 0xFF) + ((bytes[5] & 0xFF) << 8) + ((bytes[6] & 0xFF) << 16) + 1;
81          this.canvasHeight = (bytes[7] & 0xFF) + ((bytes[8] & 0xFF) << 8) + ((bytes[9] & 0xFF) << 16) + 1;
82  
83          if (canvasWidth * canvasHeight < 0) {
84              throw new ImagingException("Illegal canvas size");
85          }
86      }
87  
88      @Override
89      public void dump(final PrintWriter pw, final int offset) throws ImagingException, IOException {
90          super.dump(pw, offset);
91          pw.println("  ICCP: " + hasIcc());
92          pw.println("  Alpha: " + hasAlpha());
93          pw.println("  EXIF: " + hasExif());
94          pw.println("  XMP: " + hasXmp());
95          pw.println("  Animation: " + hasAnimation());
96          pw.println("  Canvas Width: " + getCanvasWidth());
97          pw.println("  Canvas Height: " + getCanvasHeight());
98      }
99  
100     /**
101      * @return the canvas height.
102      */
103     public int getCanvasHeight() {
104         return canvasHeight;
105     }
106 
107     /**
108      * @return the canvas width.
109      */
110     public int getCanvasWidth() {
111         return canvasWidth;
112     }
113 
114     /**
115      * @return whether the chunk has alpha enabled.
116      */
117     public boolean hasAlpha() {
118         return hasAlpha;
119     }
120 
121     /**
122      * @return if the chunk contains an animation.
123      */
124     public boolean hasAnimation() {
125         return hasAnimation;
126     }
127 
128     /**
129      * @return whether the chunk has EXIF data.
130      */
131     public boolean hasExif() {
132         return hasExif;
133     }
134 
135     /**
136      * @return whether the chunk has ICC enabled.
137      */
138     public boolean hasIcc() {
139         return hasIcc;
140     }
141 
142     /**
143      * @return whether the chunk has XMP.
144      */
145     public boolean hasXmp() {
146         return hasXmp;
147     }
148 }