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; 023 024/** 025 * VP8X (descriptions of features used) chunk. 026 * 027 * <pre>{@code 028 * 0 1 2 3 029 * 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 030 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 031 * | | 032 * | WebP file header (12 bytes) | 033 * | | 034 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 035 * | ChunkHeader('VP8X') | 036 * | | 037 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 038 * |Rsv|I|L|E|X|A|R| Reserved | 039 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 040 * | Canvas Width Minus One | ... 041 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 042 * ... Canvas Height Minus One | 043 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 044 * }</pre> 045 * 046 * @see <a href="https://developers.google.com/speed/webp/docs/riff_container#extended_file_format">Extended File Format</a> 047 * @since 1.0-alpha4 048 */ 049public final class WebPChunkVp8x extends WebPChunk { 050 private final boolean hasIcc; 051 private final boolean hasAlpha; 052 private final boolean hasExif; 053 private final boolean hasXmp; 054 private final boolean hasAnimation; 055 private final int canvasWidth; 056 private final int canvasHeight; 057 058 /** 059 * Create a VP8x chunk. 060 * 061 * @param type VP8X chunk type 062 * @param size VP8X chunk size 063 * @param bytes VP8X chunk data 064 * @throws ImagingException if the chunk data and the size provided do not match, or if the other parameters provided are invalid. 065 */ 066 public WebPChunkVp8x(final int type, final int size, final byte[] bytes) throws ImagingException { 067 super(type, size, bytes); 068 069 if (size != 10) { 070 throw new ImagingException("VP8X chunk size must be 10"); 071 } 072 073 final int mark = bytes[0] & 0xFF; 074 this.hasIcc = (mark & 0b0010_0000) != 0; 075 this.hasAlpha = (mark & 0b0001_0000) != 0; 076 this.hasExif = (mark & 0b0000_1000) != 0; 077 this.hasXmp = (mark & 0b0000_0100) != 0; 078 this.hasAnimation = (mark & 0b0000_0010) != 0; 079 080 this.canvasWidth = (bytes[4] & 0xFF) + ((bytes[5] & 0xFF) << 8) + ((bytes[6] & 0xFF) << 16) + 1; 081 this.canvasHeight = (bytes[7] & 0xFF) + ((bytes[8] & 0xFF) << 8) + ((bytes[9] & 0xFF) << 16) + 1; 082 083 if (canvasWidth * canvasHeight < 0) { 084 throw new ImagingException("Illegal canvas size"); 085 } 086 } 087 088 @Override 089 public void dump(final PrintWriter pw, final int offset) throws ImagingException, IOException { 090 super.dump(pw, offset); 091 pw.println(" ICCP: " + hasIcc()); 092 pw.println(" Alpha: " + hasAlpha()); 093 pw.println(" EXIF: " + hasExif()); 094 pw.println(" XMP: " + hasXmp()); 095 pw.println(" Animation: " + hasAnimation()); 096 pw.println(" Canvas Width: " + getCanvasWidth()); 097 pw.println(" Canvas Height: " + getCanvasHeight()); 098 } 099 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}