001/******************************************************************************* 002 * This software is provided as a supplement to the authors' textbooks on digital 003 * image processing published by Springer-Verlag in various languages and editions. 004 * Permission to use and distribute this software is granted under the BSD 2-Clause 005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 006 * Copyright (c) 2006-2023 Wilhelm Burger, Mark J. Burge. All rights reserved. 007 * Visit https://imagingbook.com for additional details. 008 ******************************************************************************/ 009package imagingbook.common.util.bits; 010 011/** 012 * This interface defines the behavior of bit vectors, i.e., fixed-sized vectors with single bit elements. This is 013 * similar to the standard Java class {@link java.util.BitSet}, which implements variable-sized vectors and additional 014 * functionality. 015 * 016 * @author WB 017 */ 018public interface BitVector { 019 020 /** 021 * Returns {@code true} is the specified bit-element is set (1), {@code false} otherwise (0). 022 * 023 * @param i the element index 024 * @return as described 025 */ 026 public boolean get(int i); 027 028 /** 029 * Sets the specified bit-element to the given boolean value (1 for {@code true}, 0 for {@code false}). 030 * 031 * @param i the element index 032 * @param val a boolean value 033 */ 034 public default void set(int i, boolean val) { 035 if (val) 036 this.set(i); 037 else 038 this.unset(i); 039 } 040 041 /** 042 * Sets the specified element (to bit-value 1). 043 * @param i the element index 044 */ 045 public void set(int i); 046 047 /** 048 * Unsets the specified element (to bit-value 0). 049 * @param i the element index 050 */ 051 public void unset(int i); 052 053 /** 054 * Sets all element values to 1. 055 */ 056 public void setAll(); 057 058 /** 059 * Sets all element values to 0. 060 */ 061 public void unsetAll(); 062 063 /** 064 * Returns the length of this bit vector. 065 * @return the length of this bit vector 066 */ 067 public int getLength(); 068 069 /** 070 * Returns the contents of this bit vector as a {@code byte} array. Bit-value 0 maps to byte value 0, value 1 maps 071 * to 1. 072 * 073 * @return a {@code byte} array 074 */ 075 public default byte[] toByteArray() { 076 byte[] bytes = new byte[this.getLength()]; 077 for (int i = 0; i < bytes.length; i++) { 078 if (get(i)) { 079 bytes[i] = 1; 080 } 081 } 082 return bytes; 083 } 084 085 /** 086 * Returns the contents of this bit vector as a {@code boolean} array. Bit-value 0 maps to false, value 1 maps to 087 * true. 088 * 089 * @return a {@code boolean} array 090 */ 091 public default boolean[] toBooleanArray() { 092 boolean[] bools = new boolean[this.getLength()]; 093 for (int i = 0; i < bools.length; i++) { 094 bools[i] = get(i); 095 } 096 return bools; 097 } 098 099 // static factory methods ----------------------------------------------- 100 101 /** 102 * Creates and returns a new bitvector of type {@link BitVector64} from the specified {@code byte} array. Each byte 103 * element b is interpreted as 0/false if b = 0 and 1/true otherwise. 104 * 105 * @param bytes an array of byte values 106 * @return a new bit vector 107 */ 108 public static BitVector from(byte[] bytes) { 109 return new BitVector64(bytes); 110 } 111 112 /** 113 * Creates and returns a new bitvector of type {@link BitVector64} from the specified {@code boolean} array, setting 114 * elements to 0/false or 1/true. 115 * 116 * @param bools an array of boolean values 117 * @return a new bit vector 118 */ 119 public static BitVector from(boolean[] bools) { 120 return new BitVector64(bools); 121 } 122 123 /** 124 * Creates and returns a new bitvector of type {@link BitVector64} with the specified length. Elements are 125 * initialized to 0/false. 126 * 127 * @param length the length of the bit vector 128 * @return a new bit vector 129 */ 130 public static BitVector create(int length) { 131 return new BitVector64(length); 132 } 133 134 /** 135 * Binarizes the specified {@code byte[]} by replacing all non-zero values by 1. Returns a new array, the original 136 * array is not modified. 137 * 138 * @param b a {@code byte[]} 139 * @return a new {@code byte[]} with values 0/1 only 140 */ 141 public static byte[] binarize(byte[] b) { 142 byte[] b2 = b.clone(); 143 for (int i = 0; i < b2.length; i++) { 144 if (b2[i] != 0) { 145 b2[i] = 1; 146 } 147 } 148 return b2; 149 } 150 151}