001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.imaging.formats.webp.chunks; 018 019import java.io.IOException; 020import java.io.PrintWriter; 021 022import org.apache.commons.imaging.ImagingException; 023import org.apache.commons.imaging.internal.SafeOperations; 024 025/** 026 * VP8L (lossless bitstream) chunk. 027 * 028 * <pre>{@code 029 * 0 1 2 3 030 * 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 031 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 032 * | ChunkHeader('VP8L') | 033 * | | 034 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 035 * : VP8L data : 036 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 037 * }</pre> 038 * 039 * @see <a href="https://developers.google.com/speed/webp/docs/riff_container#simple_file_format_lossless">Simple File Format (Lossless)</a> 040 * @since 1.0-alpha4 041 */ 042public final class WebPChunkVp8l extends WebPChunk { 043 private final int imageWidth; 044 private final int imageHeight; 045 private final boolean hasAlpha; 046 private final int versionNumber; 047 048 /** 049 * Create a VP8L chunk. 050 * 051 * @param type chunk type. 052 * @param size chunk size. 053 * @param bytes chunk data. 054 * @throws ImagingException if the chunk data and the size provided do not match. 055 */ 056 public WebPChunkVp8l(final int type, final int size, final byte[] bytes) throws ImagingException { 057 super(type, size, bytes); 058 059 if (bytes[0] != 0x2f || size < 5) { 060 throw new ImagingException("Invalid VP8L chunk"); 061 } 062 063 final int b1 = bytes[1] & 0xFF; 064 final int b2 = bytes[2] & 0xFF; 065 final int b3 = bytes[3] & 0xFF; 066 final int b4 = bytes[4] & 0xFF; 067 068 this.imageWidth = b1 + ((b2 & 0b0011_1111) << 8) + 1; 069 this.imageHeight = SafeOperations.add((b2 & 0b1100_0000) >> 6, b3 << 2, (b4 & 0b1111) << 8, 1); 070 this.hasAlpha = (b4 & 0b0001_0000) != 0; 071 this.versionNumber = b4 >> 5; 072 073 if (versionNumber != 0) { 074 throw new ImagingException("VP8L version should be 0"); 075 } 076 } 077 078 @Override 079 public void dump(final PrintWriter pw, final int offset) throws ImagingException, IOException { 080 super.dump(pw, offset); 081 pw.println(" Version Number: " + getVersionNumber()); 082 pw.println(" Image Width: " + getImageWidth()); 083 pw.println(" Image Height: " + getImageHeight()); 084 pw.println(" Alpha: " + hasAlpha()); 085 } 086 087 /** 088 * @return the image height. 089 */ 090 public int getImageHeight() { 091 return imageHeight; 092 } 093 094 /** 095 * @return the image width. 096 */ 097 public int getImageWidth() { 098 return imageWidth; 099 } 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}