1 /*
2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package com.sun.imageio.plugins.tiff;
26 
27 import javax.imageio.metadata.IIOMetadata;
28 import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
29 import javax.imageio.plugins.tiff.TIFFField;
30 
31 /**
32  *
33  */
34 abstract class TIFFFaxCompressor extends TIFFCompressor {
35 
36      /**
37      * The CCITT numerical definition of white.
38      */
39     protected static final int WHITE = 0;
40 
41     /**
42      * The CCITT numerical definition of black.
43      */
44     protected static final int BLACK = 1;
45 
46     // --- Begin tables for CCITT compression ---
47 
48     protected static final byte[] byteTable = new byte[] {
49         8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,     // 0 to 15
50         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,     // 16 to 31
51         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,     // 32 to 47
52         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,     // 48 to 63
53         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     // 64 to 79
54         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     // 80 to 95
55         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     // 96 to 111
56         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     // 112 to 127
57         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     // 128 to 143
58         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     // 144 to 159
59         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     // 160 to 175
60         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     // 176 to 191
61         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     // 192 to 207
62         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     // 208 to 223
63         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     // 224 to 239
64         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0      // 240 to 255
65     };
66 
67     /**
68      * Terminating codes for black runs.
69      */
70     protected static final int[] termCodesBlack = new int[] {
71         /*     0 0x0000 */     0x0dc0000a, 0x40000003, 0xc0000002, 0x80000002,
72         /*     4 0x0004 */     0x60000003, 0x30000004, 0x20000004, 0x18000005,
73         /*     8 0x0008 */     0x14000006, 0x10000006, 0x08000007, 0x0a000007,
74         /*    12 0x000c */     0x0e000007, 0x04000008, 0x07000008, 0x0c000009,
75         /*    16 0x0010 */     0x05c0000a, 0x0600000a, 0x0200000a, 0x0ce0000b,
76         /*    20 0x0014 */     0x0d00000b, 0x0d80000b, 0x06e0000b, 0x0500000b,
77         /*    24 0x0018 */     0x02e0000b, 0x0300000b, 0x0ca0000c, 0x0cb0000c,
78         /*    28 0x001c */     0x0cc0000c, 0x0cd0000c, 0x0680000c, 0x0690000c,
79         /*    32 0x0020 */     0x06a0000c, 0x06b0000c, 0x0d20000c, 0x0d30000c,
80         /*    36 0x0024 */     0x0d40000c, 0x0d50000c, 0x0d60000c, 0x0d70000c,
81         /*    40 0x0028 */     0x06c0000c, 0x06d0000c, 0x0da0000c, 0x0db0000c,
82         /*    44 0x002c */     0x0540000c, 0x0550000c, 0x0560000c, 0x0570000c,
83         /*    48 0x0030 */     0x0640000c, 0x0650000c, 0x0520000c, 0x0530000c,
84         /*    52 0x0034 */     0x0240000c, 0x0370000c, 0x0380000c, 0x0270000c,
85         /*    56 0x0038 */     0x0280000c, 0x0580000c, 0x0590000c, 0x02b0000c,
86         /*    60 0x003c */     0x02c0000c, 0x05a0000c, 0x0660000c, 0x0670000c
87     };
88 
89     /**
90      * Terminating codes for white runs.
91      */
92     protected static final int[] termCodesWhite = new int[] {
93         /*     0 0x0000 */     0x35000008, 0x1c000006, 0x70000004, 0x80000004,
94         /*     4 0x0004 */     0xb0000004, 0xc0000004, 0xe0000004, 0xf0000004,
95         /*     8 0x0008 */     0x98000005, 0xa0000005, 0x38000005, 0x40000005,
96         /*    12 0x000c */     0x20000006, 0x0c000006, 0xd0000006, 0xd4000006,
97         /*    16 0x0010 */     0xa8000006, 0xac000006, 0x4e000007, 0x18000007,
98         /*    20 0x0014 */     0x10000007, 0x2e000007, 0x06000007, 0x08000007,
99         /*    24 0x0018 */     0x50000007, 0x56000007, 0x26000007, 0x48000007,
100         /*    28 0x001c */     0x30000007, 0x02000008, 0x03000008, 0x1a000008,
101         /*    32 0x0020 */     0x1b000008, 0x12000008, 0x13000008, 0x14000008,
102         /*    36 0x0024 */     0x15000008, 0x16000008, 0x17000008, 0x28000008,
103         /*    40 0x0028 */     0x29000008, 0x2a000008, 0x2b000008, 0x2c000008,
104         /*    44 0x002c */     0x2d000008, 0x04000008, 0x05000008, 0x0a000008,
105         /*    48 0x0030 */     0x0b000008, 0x52000008, 0x53000008, 0x54000008,
106         /*    52 0x0034 */     0x55000008, 0x24000008, 0x25000008, 0x58000008,
107         /*    56 0x0038 */     0x59000008, 0x5a000008, 0x5b000008, 0x4a000008,
108         /*    60 0x003c */     0x4b000008, 0x32000008, 0x33000008, 0x34000008
109     };
110 
111     /**
112      * Make-up codes for black runs.
113      */
114     protected static final int[] makeupCodesBlack = new int[] {
115         /*     0 0x0000 */     0x00000000, 0x03c0000a, 0x0c80000c, 0x0c90000c,
116         /*     4 0x0004 */     0x05b0000c, 0x0330000c, 0x0340000c, 0x0350000c,
117         /*     8 0x0008 */     0x0360000d, 0x0368000d, 0x0250000d, 0x0258000d,
118         /*    12 0x000c */     0x0260000d, 0x0268000d, 0x0390000d, 0x0398000d,
119         /*    16 0x0010 */     0x03a0000d, 0x03a8000d, 0x03b0000d, 0x03b8000d,
120         /*    20 0x0014 */     0x0290000d, 0x0298000d, 0x02a0000d, 0x02a8000d,
121         /*    24 0x0018 */     0x02d0000d, 0x02d8000d, 0x0320000d, 0x0328000d,
122         /*    28 0x001c */     0x0100000b, 0x0180000b, 0x01a0000b, 0x0120000c,
123         /*    32 0x0020 */     0x0130000c, 0x0140000c, 0x0150000c, 0x0160000c,
124         /*    36 0x0024 */     0x0170000c, 0x01c0000c, 0x01d0000c, 0x01e0000c,
125         /*    40 0x0028 */     0x01f0000c, 0x00000000, 0x00000000, 0x00000000,
126         /*    44 0x002c */     0x00000000, 0x00000000, 0x00000000, 0x00000000,
127         /*    48 0x0030 */     0x00000000, 0x00000000, 0x00000000, 0x00000000,
128         /*    52 0x0034 */     0x00000000, 0x00000000, 0x00000000, 0x00000000,
129         /*    56 0x0038 */     0x00000000, 0x00000000, 0x00000000, 0x00000000
130     };
131 
132     /**
133      * Make-up codes for white runs.
134      */
135     protected static final int[] makeupCodesWhite = new int[] {
136         /*     0 0x0000 */     0x00000000, 0xd8000005, 0x90000005, 0x5c000006,
137         /*     4 0x0004 */     0x6e000007, 0x36000008, 0x37000008, 0x64000008,
138         /*     8 0x0008 */     0x65000008, 0x68000008, 0x67000008, 0x66000009,
139         /*    12 0x000c */     0x66800009, 0x69000009, 0x69800009, 0x6a000009,
140         /*    16 0x0010 */     0x6a800009, 0x6b000009, 0x6b800009, 0x6c000009,
141         /*    20 0x0014 */     0x6c800009, 0x6d000009, 0x6d800009, 0x4c000009,
142         /*    24 0x0018 */     0x4c800009, 0x4d000009, 0x60000006, 0x4d800009,
143         /*    28 0x001c */     0x0100000b, 0x0180000b, 0x01a0000b, 0x0120000c,
144         /*    32 0x0020 */     0x0130000c, 0x0140000c, 0x0150000c, 0x0160000c,
145         /*    36 0x0024 */     0x0170000c, 0x01c0000c, 0x01d0000c, 0x01e0000c,
146         /*    40 0x0028 */     0x01f0000c, 0x00000000, 0x00000000, 0x00000000,
147         /*    44 0x002c */     0x00000000, 0x00000000, 0x00000000, 0x00000000,
148         /*    48 0x0030 */     0x00000000, 0x00000000, 0x00000000, 0x00000000,
149         /*    52 0x0034 */     0x00000000, 0x00000000, 0x00000000, 0x00000000,
150         /*    56 0x0038 */     0x00000000, 0x00000000, 0x00000000, 0x00000000
151     };
152 
153     /**
154      * Pass mode table.
155      */
156     protected static final int[] passMode = new int[] {
157         0x10000004            // 0001
158     };
159 
160     /**
161      * Vertical mode table.
162      */
163     protected static final int[] vertMode = new int[] {
164         0x06000007,            // 0000011
165         0x0c000006,            // 000011
166         0x60000003,            // 011
167         0x80000001,            // 1
168         0x40000003,            // 010
169         0x08000006,            // 000010
170         0x04000007            // 0000010
171     };
172 
173     /**
174      * Horizontal mode table.
175      */
176     protected static final int[] horzMode = new int[] {
177         0x20000003            // 001
178     };
179 
180     /**
181      * Black and white terminating code table.
182      */
183     protected static final int[][] termCodes =
184         new int[][] {termCodesWhite, termCodesBlack};
185 
186     /**
187      * Black and white make-up code table.
188      */
189     protected static final int[][] makeupCodes =
190         new int[][] {makeupCodesWhite, makeupCodesBlack};
191 
192     /**
193      * Black and white pass mode table.
194      */
195     protected static final int[][] pass = new int[][] {passMode, passMode};
196 
197     /**
198      * Black and white vertical mode table.
199      */
200     protected static final int[][] vert = new int[][] {vertMode, vertMode};
201 
202     /**
203      * Black and white horizontal mode table.
204      */
205     protected static final int[][] horz = new int[][] {horzMode, horzMode};
206 
207     // --- End tables for CCITT compression ---
208 
209     /**
210      * Whether bits are inserted in reverse order (TIFF FillOrder 2).
211      */
212     protected boolean inverseFill = false;
213 
214     /**
215      * Output bit buffer.
216      */
217     protected int bits;
218 
219     /**
220      * Number of bits in the output bit buffer.
221      */
222     protected int ndex;
223 
224     /**
225      * Constructor. The superclass constructor is merely invoked with the
226      * same parameters.
227      */
TIFFFaxCompressor(String compressionType, int compressionTagValue, boolean isCompressionLossless)228     protected TIFFFaxCompressor(String compressionType,
229                                 int compressionTagValue,
230                                 boolean isCompressionLossless) {
231         super(compressionType, compressionTagValue, isCompressionLossless);
232     }
233 
234     /**
235      * Sets the value of the {@code metadata} field.
236      *
237      * <p> The implementation in this class also sets local options
238      * from the FILL_ORDER field if it exists.</p>
239      *
240      * @param metadata the {@code IIOMetadata} object for the
241      * image being written.
242      *
243      * @see #getMetadata()
244      */
setMetadata(IIOMetadata metadata)245     public void setMetadata(IIOMetadata metadata) {
246         super.setMetadata(metadata);
247 
248         if (metadata instanceof TIFFImageMetadata) {
249             TIFFImageMetadata tim = (TIFFImageMetadata)metadata;
250             TIFFField f = tim.getTIFFField(BaselineTIFFTagSet.TAG_FILL_ORDER);
251             inverseFill = (f != null && f.getAsInt(0) == 2);
252         }
253     }
254 
255     /**
256      * Return min of {@code maxOffset} or offset of first pixel
257      * different from pixel at {@code bitOffset}.
258      */
nextState(byte[] data, int base, int bitOffset, int maxOffset)259     public int nextState(byte[] data,
260                           int    base,
261                           int    bitOffset,
262                           int    maxOffset)
263     {
264         if(data == null) {
265             return maxOffset;
266         }
267 
268         int next  = base + (bitOffset>>>3);
269         // If the offset is beyond the data already then the minimum of the
270         // current offset and maxOffset must be maxOffset.
271         if(next >= data.length) {
272             return maxOffset;
273         }
274         int end   = base + (maxOffset>>>3);
275         if(end == data.length) { // Prevents out of bounds exception below
276             end--;
277         }
278         int extra = bitOffset & 0x7;
279 
280         int  testbyte;
281 
282         if((data[next] & (0x80 >>> extra)) != 0) {    // look for "0"
283             testbyte = ~(data[next]) & (0xff >>> extra);
284             while (next < end) {
285                 if (testbyte != 0) {
286                     break;
287                 }
288                 testbyte = ~(data[++next]) & 0xff;
289             }
290         } else {                // look for "1"
291             if ((testbyte = (data[next] & (0xff >>> extra))) != 0) {
292                 bitOffset = (next-base)*8 + byteTable[testbyte];
293                 return ((bitOffset < maxOffset) ? bitOffset : maxOffset);
294             }
295             while (next < end) {
296                 if ((testbyte = data[++next]&0xff) != 0) {
297                     // "1" is in current byte
298                     bitOffset = (next-base)*8 + byteTable[testbyte];
299                     return ((bitOffset < maxOffset) ? bitOffset : maxOffset);
300                 }
301             }
302         }
303         bitOffset = (next-base)*8 + byteTable[testbyte];
304         return ((bitOffset < maxOffset) ? bitOffset : maxOffset);
305     }
306 
307     /**
308      * Initialize bit buffer machinery.
309      */
initBitBuf()310     public void initBitBuf()
311     {
312         ndex = 0;
313         bits = 0x00000000;
314     }
315 
316     /**
317      * Get code for run and add to compressed bitstream.
318      */
add1DBits(byte[] buf, int where, int count, int color)319     public int add1DBits(byte[] buf,
320                           int    where, // byte offs
321                           int    count, // #pixels in run
322                           int    color) // color of run
323     {
324         int                 sixtyfours;
325         int        mask;
326         int len = where;
327 
328         sixtyfours = count >>> 6;    // count / 64;
329         count = count & 0x3f;       // count % 64
330         if (sixtyfours != 0) {
331             for ( ; sixtyfours > 40; sixtyfours -= 40) {
332                 mask = makeupCodes[color][40];
333                 bits |= (mask & 0xfff80000) >>> ndex;
334                 ndex += (mask & 0x0000ffff);
335                 while (ndex > 7) {
336                     buf[len++] = (byte)(bits >>> 24);
337                     bits <<= 8;
338                     ndex -= 8;
339                 }
340             }
341 
342             mask = makeupCodes[color][sixtyfours];
343             bits |= (mask & 0xfff80000) >>> ndex;
344             ndex += (mask & 0x0000ffff);
345             while (ndex > 7) {
346                 buf[len++] = (byte)(bits >>> 24);
347                 bits <<= 8;
348                 ndex -= 8;
349             }
350         }
351 
352         mask = termCodes[color][count];
353         bits |= (mask & 0xfff80000) >>> ndex;
354         ndex += (mask & 0x0000ffff);
355         while (ndex > 7) {
356             buf[len++] = (byte)(bits >>> 24);
357             bits <<= 8;
358             ndex -= 8;
359         }
360 
361         return(len - where);
362     }
363 
364     /**
365      * Place entry from mode table into compressed bitstream.
366      */
add2DBits(byte[] buf, int where, int[][] mode, int entry)367     public int add2DBits(byte[]  buf,   // compressed buffer
368                           int     where, // byte offset into compressed buffer
369                           int[][] mode,  // 2-D mode to be encoded
370                           int     entry) // mode entry (0 unless vertical)
371     {
372         int        mask;
373         int len = where;
374         int                 color = 0;
375 
376         mask = mode[color][entry];
377         bits |= (mask & 0xfff80000) >>> ndex;
378         ndex += (mask & 0x0000ffff);
379         while (ndex > 7) {
380             buf[len++] = (byte)(bits >>> 24);
381             bits <<= 8;
382             ndex -= 8;
383         }
384 
385         return(len - where);
386     }
387 
388     /**
389      * Add an End-of-Line (EOL == 0x001) to the compressed bitstream
390      * with optional byte alignment.
391      */
addEOL(boolean is1DMode, boolean addFill, boolean add1, byte[] buf, int where)392     public int addEOL(boolean is1DMode,// 1D encoding
393                        boolean addFill, // byte aligned EOLs
394                        boolean add1,    // add1 ? EOL+1 : EOL+0
395                        byte[]  buf,     // compressed buffer address
396                        int     where)   // current byte offset into buffer
397     {
398         int len = where;
399 
400         //
401         // Add zero-valued fill bits such that the EOL is aligned as
402         //
403         //     xxxx 0000 0000 0001
404         //
405         if(addFill) {
406             //
407             // Simply increment the bit count. No need to feed bits into
408             // the output buffer at this point as there are at most 7 bits
409             // in the bit buffer, at most 7 are added here, and at most
410             // 13 below making the total 7+7+13 = 27 before the bit feed
411             // at the end of this routine.
412             //
413             ndex += ((ndex <= 4) ? 4 - ndex : 12 - ndex);
414         }
415 
416         //
417         // Write EOL into buffer
418         //
419         if(is1DMode) {
420             bits |= 0x00100000 >>> ndex;
421             ndex += 12;
422         } else {
423             bits |= (add1 ? 0x00180000 : 0x00100000) >>> ndex;
424             ndex += 13;
425         }
426 
427         while (ndex > 7) {
428             buf[len++] = (byte)(bits >>> 24);
429             bits <<= 8;
430             ndex -= 8;
431         }
432 
433         return(len - where);
434     }
435 
436     /**
437      * Add an End-of-Facsimile-Block (EOFB == 0x001001) to the compressed
438      * bitstream.
439      */
addEOFB(byte[] buf, int where)440     public int addEOFB(byte[] buf,    // compressed buffer
441                          int    where) // byte offset into compressed buffer
442     {
443         int len = where;
444 
445         //
446         // eofb code
447         //
448         bits |= 0x00100100 >>> ndex;
449 
450         //
451         // eofb code length
452         //
453         ndex += 24;
454 
455         //
456         // flush all pending bits
457         //
458         while(ndex > 0) {
459             buf[len++] = (byte)(bits >>> 24);
460             bits <<= 8;
461             ndex -= 8;
462         }
463 
464         return(len - where);
465     }
466 
467     /**
468      * One-dimensionally encode a row of data using CCITT Huffman compression.
469      * The bit buffer should be initialized as required before invoking this
470      * method and should be flushed after the method returns. The fill order
471      * is always highest-order to lowest-order bit so the calling routine
472      * should handle bit inversion.
473      */
encode1D(byte[] data, int rowOffset, int colOffset, int rowLength, byte[] compData, int compOffset)474     public int encode1D(byte[] data,
475                          int rowOffset,
476                          int colOffset,
477                          int rowLength,
478                          byte[] compData,
479                          int compOffset) {
480         int lineAddr = rowOffset;
481         int bitIndex = colOffset;
482 
483         int last     = bitIndex + rowLength;
484         int outIndex = compOffset;
485 
486         //
487         // Is first pixel black
488         //
489         int testbit =
490             ((data[lineAddr + (bitIndex>>>3)]&0xff) >>>
491              (7-(bitIndex & 0x7))) & 0x1;
492         int currentColor = BLACK;
493         if (testbit != 0) {
494             outIndex += add1DBits(compData, outIndex, 0, WHITE);
495         } else {
496             currentColor = WHITE;
497         }
498 
499         //
500         // Run-length encode line
501         //
502         while (bitIndex < last) {
503             int bitCount =
504                 nextState(data, lineAddr, bitIndex, last) - bitIndex;
505             outIndex +=
506                 add1DBits(compData, outIndex, bitCount, currentColor);
507             bitIndex += bitCount;
508             currentColor ^= 0x00000001;
509         }
510 
511         return outIndex - compOffset;
512     }
513 }
514