1 package nom.tam.image.compression.tile;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 import java.nio.ByteBuffer;
35
36 import nom.tam.image.compression.tile.mask.ImageNullPixelMask;
37 import nom.tam.image.compression.tile.mask.NullPixelMaskPreserver;
38 import nom.tam.image.tile.operation.TileArea;
39 import nom.tam.util.type.ElementType;
40
41
42
43
44
45
46
47 public class TileCompressor extends TileCompressionOperation {
48
49 private boolean forceNoLoss = false;
50
51 private NullPixelMaskPreserver nullPixelMaskPerserver;
52
53
54
55
56
57
58
59
60 protected TileCompressor(TiledImageCompressionOperation array, int tileIndex, TileArea area) {
61 super(array, tileIndex, area);
62 }
63
64 @Override
65 public void run() {
66 compress();
67 }
68
69
70
71
72
73 private synchronized void compactCompressedData() {
74 if (getTileIndex() > 0) {
75
76 getPreviousTileOperation().waitForResult();
77 ByteBuffer compressedWholeArea = getCompressedWholeArea();
78 compressedOffset = compressedWholeArea.position();
79 ElementType.BYTE.appendBuffer(compressedWholeArea, compressedData);
80 replaceCompressedBufferWithTargetArea(compressedWholeArea);
81 } else {
82 compressedOffset = 0;
83 getCompressedWholeArea().position(compressedData.limit());
84 }
85 }
86
87 private synchronized void compress() {
88 initTileOptions();
89
90 compressedData.limit(getTileBuffer().getPixelSize() * getBaseType().size());
91 compressionType = TileCompressionType.COMPRESSED;
92 boolean compressSuccess = false;
93 boolean tryNormalCompression = !(tileOptions.isLossyCompression() && forceNoLoss);
94
95 tileOptions.getCompressionParameters().setTileIndex(getTileIndex());
96
97 if (tryNormalCompression) {
98 compressSuccess = getCompressorControl().compress(getTileBuffer().getBuffer(), compressedData, tileOptions);
99 if (compressSuccess) {
100 if (nullPixelMaskPerserver != null) {
101 nullPixelMaskPerserver.preserveNull();
102 }
103 tileOptions.getCompressionParameters().setValuesInColumn(getTileIndex());
104 }
105 }
106
107 if (!compressSuccess) {
108 compressionType = TileCompressionType.GZIP_COMPRESSED;
109 compressedData.rewind();
110 getTileBuffer().getBuffer().rewind();
111 compressSuccess = getGzipCompressorControl().compress(getTileBuffer().getBuffer(), compressedData, null);
112 if (compressSuccess) {
113 tileOptions.getCompressionParameters().setValuesInColumn(getTileIndex());
114 }
115 }
116
117 if (!compressSuccess) {
118 compressionType = TileCompressionType.UNCOMPRESSED;
119 compressedData.rewind();
120 getTileBuffer().getBuffer().rewind();
121 getBaseType().appendToByteBuffer(compressedData, getTileBuffer().getBuffer());
122 }
123
124 compressedData.limit(compressedData.position());
125 compressedData.rewind();
126
127 compactCompressedData();
128 }
129
130 private synchronized void replaceCompressedBufferWithTargetArea(ByteBuffer compressedWholeArea) {
131 int compressedSize = compressedData.limit();
132 int latest = compressedWholeArea.position();
133 compressedWholeArea.position(compressedOffset);
134 compressedData = compressedWholeArea.slice();
135 compressedData.limit(compressedSize);
136 compressedWholeArea.position(latest);
137 }
138
139 @Override
140 protected synchronized NullPixelMaskPreserver createImageNullPixelMask(ImageNullPixelMask imageNullPixelMask) {
141 if (imageNullPixelMask != null) {
142 nullPixelMaskPerserver = imageNullPixelMask.createTilePreserver(getTileBuffer(), getTileIndex());
143 }
144 return nullPixelMaskPerserver;
145 }
146
147 @Override
148 protected synchronized void forceNoLoss(boolean value) {
149 forceNoLoss = value;
150 }
151 }