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 import org.apache.commons.imaging.internal.SafeOperations;
24
25 /**
26 * VP8L (lossless bitstream) chunk.
27 *
28 * <pre>{@code
29 * 0 1 2 3
30 * 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
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | ChunkHeader('VP8L') |
33 * | |
34 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 * : VP8L data :
36 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 * }</pre>
38 *
39 * @see <a href="https://developers.google.com/speed/webp/docs/riff_container#simple_file_format_lossless">Simple File Format (Lossless)</a>
40 * @since 1.0.0-alpha4
41 */
42 public final class WebPChunkVp8l extends AbstractWebPChunk {
43 private final int imageWidth;
44 private final int imageHeight;
45 private final boolean hasAlpha;
46 private final int versionNumber;
47
48 /**
49 * Create a VP8L chunk.
50 *
51 * @param type chunk type.
52 * @param size chunk size.
53 * @param bytes chunk data.
54 * @throws ImagingException if the chunk data and the size provided do not match.
55 */
56 public WebPChunkVp8l(final int type, final int size, final byte[] bytes) throws ImagingException {
57 super(type, size, bytes);
58
59 if (bytes[0] != 0x2f || size < 5) {
60 throw new ImagingException("Invalid VP8L chunk");
61 }
62
63 final int b1 = bytes[1] & 0xFF;
64 final int b2 = bytes[2] & 0xFF;
65 final int b3 = bytes[3] & 0xFF;
66 final int b4 = bytes[4] & 0xFF;
67
68 this.imageWidth = b1 + ((b2 & 0b0011_1111) << 8) + 1;
69 this.imageHeight = SafeOperations.add((b2 & 0b1100_0000) >> 6, b3 << 2, (b4 & 0b1111) << 8, 1);
70 this.hasAlpha = (b4 & 0b0001_0000) != 0;
71 this.versionNumber = b4 >> 5;
72
73 if (versionNumber != 0) {
74 throw new ImagingException("VP8L version should be 0");
75 }
76 }
77
78 @Override
79 public void dump(final PrintWriter pw, final int offset) throws ImagingException, IOException {
80 super.dump(pw, offset);
81 pw.println(" Version Number: " + getVersionNumber());
82 pw.println(" Image Width: " + getImageWidth());
83 pw.println(" Image Height: " + getImageHeight());
84 pw.println(" Alpha: " + hasAlpha());
85 }
86
87 /**
88 * @return the image height.
89 */
90 public int getImageHeight() {
91 return imageHeight;
92 }
93
94 /**
95 * @return the image width.
96 */
97 public int getImageWidth() {
98 return imageWidth;
99 }
100
101 /**
102 * @return the version number.
103 */
104 public int getVersionNumber() {
105 return versionNumber;
106 }
107
108 /**
109 * @return whether the image has an alpha channel or not.
110 */
111 public boolean hasAlpha() {
112 return hasAlpha;
113 }
114 }