1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.bmp;
18
19 import java.awt.image.BufferedImage;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22
23 import org.apache.commons.imaging.common.BinaryOutputStream;
24 import org.apache.commons.imaging.palette.SimplePalette;
25
26 final class BmpWriterPalette implements BmpWriter {
27
28 private final SimplePalette palette;
29 private final int bitsPerSample;
30
31 BmpWriterPalette(final SimplePalette palette) {
32 this.palette = palette;
33
34 if (palette.length() <= 2) {
35 bitsPerSample = 1;
36 } else if (palette.length() <= 16) {
37 bitsPerSample = 4;
38 } else {
39 bitsPerSample = 8;
40 }
41 }
42
43 @Override
44 public int getBitsPerPixel() {
45 return bitsPerSample;
46 }
47
48 @Override
49 public byte[] getImageData(final BufferedImage src) {
50 final int width = src.getWidth();
51 final int height = src.getHeight();
52
53 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
54
55 int bitCache = 0;
56 int bitsInCache = 0;
57
58 int byteCount = 0;
59 for (int y = height - 1; y >= 0; y--) {
60 for (int x = 0; x < width; x++) {
61 final int argb = src.getRGB(x, y);
62 final int rgb = 0xffffff & argb;
63
64 final int index = palette.getPaletteIndex(rgb);
65
66 if (bitsPerSample == 8) {
67 baos.write(0xff & index);
68 byteCount++;
69 } else {
70
71 bitCache = bitCache << bitsPerSample | index;
72 bitsInCache += bitsPerSample;
73 if (bitsInCache >= 8) {
74 baos.write(0xff & bitCache);
75 byteCount++;
76 bitCache = 0;
77 bitsInCache = 0;
78 }
79 }
80 }
81
82 if (bitsInCache > 0) {
83 bitCache = bitCache << 8 - bitsInCache;
84
85 baos.write(0xff & bitCache);
86 byteCount++;
87 bitCache = 0;
88 bitsInCache = 0;
89 }
90
91 while (byteCount % 4 != 0) {
92 baos.write(0);
93 byteCount++;
94 }
95 }
96
97 return baos.toByteArray();
98 }
99
100 @Override
101 public int getPaletteSize() {
102 return palette.length();
103 }
104
105 @Override
106 public void writePalette(final BinaryOutputStream bos) throws IOException {
107 for (int i = 0; i < palette.length(); i++) {
108 final int rgb = palette.getEntry(i);
109
110 final int red = 0xff & rgb >> 16;
111 final int green = 0xff & rgb >> 8;
112 final int blue = 0xff & rgb >> 0;
113
114 bos.write(blue);
115 bos.write(green);
116 bos.write(red);
117 bos.write(0);
118 }
119 }
120 }