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.0-alpha4
48 */
49 public final class WebPChunkVp8x extends AbstractWebPChunk {
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 }