/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.sanselan.formats.png; import java.io.IOException; import org.apache.sanselan.ImageReadException; public class BitParser { private final byte bytes[]; private final int bitsPerPixel; private final int bitDepth; public BitParser(byte bytes[], int bitsPerPixel, int bitDepth) { this.bytes = bytes; this.bitsPerPixel = bitsPerPixel; this.bitDepth = bitDepth; } public int getSample(int pixelIndexInScanline, int sampleIndex) throws ImageReadException, IOException { int pixelIndexBits = bitsPerPixel * pixelIndexInScanline; int sampleIndexBits = pixelIndexBits + (sampleIndex * bitDepth); int sampleIndexBytes = sampleIndexBits >> 3; if (bitDepth == 8) return 0xff & bytes[sampleIndexBytes]; else if (bitDepth < 8) { int b = 0xff & bytes[sampleIndexBytes]; int bitsToShift = 8 - ((pixelIndexBits & 7) + bitDepth); b >>= bitsToShift; int bitmask = (1 << bitDepth) - 1; return b & bitmask; } else if (bitDepth == 16) { return (((0xff & bytes[sampleIndexBytes]) << 8) | (0xff & bytes[sampleIndexBytes + 1])); } throw new ImageReadException("PNG: bad BitDepth: " + bitDepth); } public int getSampleAsByte(int pixelIndexInScanline, int sampleIndex) throws ImageReadException, IOException { int sample = getSample(pixelIndexInScanline, sampleIndex); int rot = 8 - bitDepth; if (rot > 0) sample <<= rot; else if (rot < 0) sample >>= -rot; return 0xff & sample; } }