1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.tiff.photometricinterpreters;
18
19 import java.io.IOException;
20 import java.util.Arrays;
21
22 import org.apache.commons.imaging.ImagingException;
23 import org.apache.commons.imaging.ImagingFormatException;
24 import org.apache.commons.imaging.common.AllocationRequestException;
25 import org.apache.commons.imaging.common.Allocator;
26 import org.apache.commons.imaging.common.ImageBuilder;
27
28 public class PhotometricInterpreterPalette extends PhotometricInterpreter {
29
30
31
32
33 private final int[] indexColorMap;
34 private final int bitsPerPixelMask;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public PhotometricInterpreterPalette(final int samplesPerPixel, final int[] bitsPerSample, final int predictor, final int width, final int height,
50 final int[] colorMap) {
51 super(samplesPerPixel, bitsPerSample, predictor, width, height);
52
53 final int bitsPerPixel = getBitsPerSample(0);
54 final int colorMapScale = 1 << bitsPerPixel;
55 int colorMapScaleX2;
56 try {
57 colorMapScaleX2 = Math.multiplyExact(2, colorMapScale);
58 } catch (final ArithmeticException e) {
59 throw new ImagingFormatException("bitsPerPixel is too large or colorMap is too small", e);
60 }
61
62
63 int maxI;
64 try {
65 maxI = Math.addExact(colorMapScaleX2, colorMapScale - 1);
66 } catch (final ArithmeticException e) {
67 throw new ImagingFormatException("bitsPerPixel is too large or colorMap is too small", e);
68 }
69 if (maxI >= colorMap.length) {
70 throw new ImagingFormatException("bitsPerPixel %,d (maxI = %,d) is too large or colorMap is too small %,d", bitsPerPixel, maxI, colorMap.length);
71 }
72 indexColorMap = Allocator.intArray(colorMapScale);
73 Arrays.setAll(indexColorMap, i -> {
74 final int red = colorMap[i] >> 8 & 0xff;
75 final int green = colorMap[i + colorMapScale] >> 8 & 0xff;
76 final int blue = colorMap[i + colorMapScaleX2] >> 8 & 0xff;
77 return 0xff000000 | red << 16 | green << 8 | blue;
78 });
79
80
81
82
83
84
85
86
87 int temp = 0;
88 for (int i = 0; i < bitsPerPixel; i++) {
89 temp = temp << 1 | 1;
90 }
91 bitsPerPixelMask = temp;
92
93 }
94
95 @Override
96 public void interpretPixel(final ImageBuilder imageBuilder, final int[] samples, final int x, final int y) throws ImagingException, IOException {
97 imageBuilder.setRgb(x, y, indexColorMap[samples[0] & bitsPerPixelMask]);
98 }
99 }