github.com/unidoc/unidoc@v2.2.0+incompatible/pdf/model/sampling/resample.go (about) 1 /* 2 * This file is subject to the terms and conditions defined in 3 * file 'LICENSE.md', which is part of this source code package. 4 */ 5 6 package sampling 7 8 // Resample the raw data which is in 8-bit (byte) format as a different 9 // bit count per sample, up to 32 bits (uint32). 10 func ResampleBytes(data []byte, bitsPerSample int) []uint32 { 11 samples := []uint32{} 12 13 bitsLeftPerSample := bitsPerSample 14 var sample uint32 15 var remainder byte 16 remainderBits := 0 17 18 index := 0 19 20 i := 0 21 for i < len(data) { 22 // Start with the remainder. 23 if remainderBits > 0 { 24 take := remainderBits 25 if bitsLeftPerSample < take { 26 take = bitsLeftPerSample 27 } 28 29 sample = (sample << uint(take)) | uint32(remainder>>uint(8-take)) 30 remainderBits -= take 31 if remainderBits > 0 { 32 remainder = remainder << uint(take) 33 } else { 34 remainder = 0 35 } 36 bitsLeftPerSample -= take 37 if bitsLeftPerSample == 0 { 38 //samples[index] = sample 39 samples = append(samples, sample) 40 bitsLeftPerSample = bitsPerSample 41 sample = 0 42 index++ 43 } 44 } else { 45 // Take next byte 46 b := data[i] 47 i++ 48 49 // 8 bits. 50 take := 8 51 if bitsLeftPerSample < take { 52 take = bitsLeftPerSample 53 } 54 remainderBits = 8 - take 55 sample = (sample << uint(take)) | uint32(b>>uint(remainderBits)) 56 57 if take < 8 { 58 remainder = b << uint(take) 59 } 60 61 bitsLeftPerSample -= take 62 if bitsLeftPerSample == 0 { 63 //samples[index] = sample 64 samples = append(samples, sample) 65 bitsLeftPerSample = bitsPerSample 66 sample = 0 67 index++ 68 } 69 } 70 } 71 72 // Take care of remaining samples (if enough data available). 73 for remainderBits >= bitsPerSample { 74 take := remainderBits 75 if bitsLeftPerSample < take { 76 take = bitsLeftPerSample 77 } 78 79 sample = (sample << uint(take)) | uint32(remainder>>uint(8-take)) 80 remainderBits -= take 81 if remainderBits > 0 { 82 remainder = remainder << uint(take) 83 } else { 84 remainder = 0 85 } 86 bitsLeftPerSample -= take 87 if bitsLeftPerSample == 0 { 88 //samples[index] = sample 89 samples = append(samples, sample) 90 bitsLeftPerSample = bitsPerSample 91 sample = 0 92 index++ 93 } 94 } 95 96 return samples 97 } 98 99 // Resample the raw data which is in <=32-bit (uint32) format as a different 100 // bit count per sample, up to 32 bits (uint32). 101 // 102 // bitsPerOutputSample is the number of bits for each output sample (up to 32) 103 // bitsPerInputSample is the number of bits used in each input sample (up to 32) 104 func ResampleUint32(data []uint32, bitsPerInputSample int, bitsPerOutputSample int) []uint32 { 105 samples := []uint32{} 106 107 bitsLeftPerSample := bitsPerOutputSample 108 var sample uint32 109 var remainder uint32 110 remainderBits := 0 111 112 index := 0 113 114 i := 0 115 for i < len(data) { 116 // Start with the remainder. 117 if remainderBits > 0 { 118 take := remainderBits 119 if bitsLeftPerSample < take { 120 take = bitsLeftPerSample 121 } 122 123 sample = (sample << uint(take)) | uint32(remainder>>uint(bitsPerInputSample-take)) 124 remainderBits -= take 125 if remainderBits > 0 { 126 remainder = remainder << uint(take) 127 } else { 128 remainder = 0 129 } 130 bitsLeftPerSample -= take 131 if bitsLeftPerSample == 0 { 132 //samples[index] = sample 133 samples = append(samples, sample) 134 bitsLeftPerSample = bitsPerOutputSample 135 sample = 0 136 index++ 137 } 138 } else { 139 // Take next byte 140 b := data[i] 141 i++ 142 143 // 32 bits. 144 take := bitsPerInputSample 145 if bitsLeftPerSample < take { 146 take = bitsLeftPerSample 147 } 148 remainderBits = bitsPerInputSample - take 149 sample = (sample << uint(take)) | uint32(b>>uint(remainderBits)) 150 151 if take < bitsPerInputSample { 152 remainder = b << uint(take) 153 } 154 155 bitsLeftPerSample -= take 156 if bitsLeftPerSample == 0 { 157 //samples[index] = sample 158 samples = append(samples, sample) 159 bitsLeftPerSample = bitsPerOutputSample 160 sample = 0 161 index++ 162 } 163 } 164 } 165 166 // Take care of remaining samples (if enough data available). 167 for remainderBits >= bitsPerOutputSample { 168 take := remainderBits 169 if bitsLeftPerSample < take { 170 take = bitsLeftPerSample 171 } 172 173 sample = (sample << uint(take)) | uint32(remainder>>uint(bitsPerInputSample-take)) 174 remainderBits -= take 175 if remainderBits > 0 { 176 remainder = remainder << uint(take) 177 } else { 178 remainder = 0 179 } 180 bitsLeftPerSample -= take 181 if bitsLeftPerSample == 0 { 182 samples = append(samples, sample) 183 bitsLeftPerSample = bitsPerOutputSample 184 sample = 0 185 index++ 186 } 187 } 188 189 // If there are partial output samples, pad with 0s. 190 if bitsLeftPerSample > 0 && bitsLeftPerSample < bitsPerOutputSample { 191 sample <<= uint(bitsLeftPerSample) 192 samples = append(samples, sample) 193 } 194 195 return samples 196 }