3444 lines
122 KiB
C
3444 lines
122 KiB
C
/****************************************************************************
|
|
CCITT.C
|
|
|
|
$Log: S:\products\msprods\oiwh\display\ccitt.c_v $
|
|
*
|
|
* Rev 1.48 03 Jun 1996 10:33:32 BEG06016
|
|
* Made CCITT decompression handle bad data a little better.
|
|
*
|
|
* Rev 1.48 03 Jun 1996 10:32:04 BEG06016
|
|
* Made CCITT decompression handle bad data a little better.
|
|
*
|
|
* Rev 1.47 01 May 1996 08:42:28 BEG06016
|
|
* Fixed a typo.
|
|
*
|
|
* Rev 1.46 30 Apr 1996 10:37:26 BEG06016
|
|
* Deleted all error checking for G3 1D decompression.
|
|
* This was commented out for Wes at Microsoft who insists on writing bad data
|
|
* out to the file.
|
|
* Wes says that if the viewer sees invalid data, then it can either pad with zeros,
|
|
* or copy the previous line to the bad line, or leave the garbage data in tact.
|
|
* This decompression engine will leave the data in tact, resulting in the user
|
|
* either seeing the correct data, or garbage (which will hopefully let them know
|
|
* that there is a problem).
|
|
* I realize that this makes us no longer TIFF compliant (Version 6, page 44 paragraph 4),
|
|
* but there is nothing we can do about that within Wes's limitations.
|
|
*
|
|
* Rev 1.45 24 Apr 1996 14:27:24 BEG06016
|
|
* Added horizontal differencing.
|
|
*
|
|
* Rev 1.44 19 Apr 1996 09:00:44 BEG06016
|
|
* Added CheckError2 for error handling.
|
|
*
|
|
* Rev 1.43 18 Apr 1996 14:45:02 BEG06016
|
|
* Added CheckError2 for error handling.
|
|
*
|
|
* Rev 1.42 16 Apr 1996 11:34:26 BEG06016
|
|
* Enlarged the allowable EOL size.
|
|
*
|
|
* Rev 1.41 14 Mar 1996 10:26:44 BEG06016
|
|
* Sped up 2D, G3T4 decompression.
|
|
*
|
|
* Rev 1.40 14 Mar 1996 09:49:20 BEG06016
|
|
* Sped up 1D decompression.
|
|
*
|
|
* Rev 1.39 12 Mar 1996 11:18:52 BEG06016
|
|
* Sped up BW decompression.
|
|
*
|
|
* Rev 1.38 28 Feb 1996 08:17:40 BEG06016
|
|
* Fixed saving of semi-valid compression types.
|
|
*
|
|
* Rev 1.37 26 Feb 1996 15:13:28 BEG06016
|
|
* Overrode user's flags when overriding their compression type
|
|
* from G32D to G42D.
|
|
*
|
|
* Rev 1.36 26 Feb 1996 10:11:42 BEG06016
|
|
* Made a temporary fix for LZW that disables Reverse bits of
|
|
* expanded data for decompression.
|
|
*
|
|
* Rev 1.35 26 Feb 1996 09:19:34 BEG06016
|
|
* Fixed some compression problems.
|
|
*
|
|
* Rev 1.34 26 Feb 1996 06:45:12 BEG06016
|
|
* Reduced safety margin on 'end of buffer' detection to better
|
|
* allow for bad heights.
|
|
*
|
|
* Rev 1.33 26 Feb 1996 06:40:32 BEG06016
|
|
* Fixed signed/unsigned mismatch.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "privdisp.h"
|
|
|
|
|
|
|
|
// CODE_WORD_BITS = the number of bits in uCodeWord that are nsed.
|
|
// CODE_WORD_SHIFT = ALWAYS 8 less than CODE_WORD_BITS. It is nsed for shifting the data and comparing.
|
|
#define CODE_WORD_BITS 32
|
|
#define CODE_WORD_SHIFT 24
|
|
#define CODE_WORD_BIT_MASK 0x80000000
|
|
|
|
int nWRunLengthToTermCode[64] ={
|
|
0x3500, 0x1c00, 0x7000, 0x8000, 0xb000, 0xc000, 0xe000, 0xf000,
|
|
0x9800, 0xa000, 0x3800, 0x4000, 0x2000, 0x0c00, 0xd000, 0xd400,
|
|
0xa800, 0xac00, 0x4e00, 0x1800, 0x1000, 0x2e00, 0x0600, 0x0800,
|
|
0x5000, 0x5600, 0x2600, 0x4800, 0x3000, 0x0200, 0x0300, 0x1a00,
|
|
0x1b00, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700, 0x2800,
|
|
0x2900, 0x2a00, 0x2b00, 0x2c00, 0x2d00, 0x0400, 0x0500, 0x0a00,
|
|
0x0b00, 0x5200, 0x5300, 0x5400, 0x5500, 0x2400, 0x2500, 0x5800,
|
|
0x5900, 0x5a00, 0x5b00, 0x4a00, 0x4b00, 0x3200, 0x3300, 0x3400};
|
|
|
|
/*
|
|
int nWRunLengthToMakeUpCodeL[41] ={
|
|
0x0000, 0xd800, 0x9000, 0x5c00, 0x6e00, 0x3600, 0x3700, 0x6400, 0x6500,
|
|
0x6800, 0x6700, 0x6600, 0x6680, 0x6900, 0x6980, 0x6a00, 0x6a80,
|
|
0x6b00, 0x6b80, 0x6c00, 0x6c80, 0x6d00, 0x6d80, 0x4c00, 0x4c80,
|
|
0x4d00, 0x6000, 0x4d80, 0x0100, 0x0180, 0x01a0, 0x0120, 0x0130,
|
|
0x0140, 0x0150, 0x0160, 0x0170, 0x01c0, 0x01d0, 0x01e0, 0x01f0};
|
|
*/
|
|
|
|
int nWRunLengthToMakeUpCodeR[41] ={
|
|
0x0000, 0x001b, 0x0012, 0x0017, 0x0037, 0x0036, 0x0037, 0x0064, 0x0065,
|
|
0x0068, 0x0067, 0x00cc, 0x00cd, 0x00d2, 0x00d3, 0x00d4, 0x00d5,
|
|
0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x0098, 0x0099,
|
|
0x009a, 0x0018, 0x009b, 0x0008, 0x000c, 0x000d, 0x0012, 0x0013,
|
|
0x0014, 0x0015, 0x0016, 0x0017, 0x001c, 0x001d, 0x001e, 0x001f};
|
|
|
|
int nWRunLengthToMakeUpCodeLength[41] ={
|
|
0, 5, 5, 6, 7, 8, 8, 8, 8,
|
|
8, 8, 9, 9, 9, 9, 9, 9,
|
|
9, 9, 9, 9, 9, 9, 9, 9,
|
|
9, 6, 9, 11, 11, 11, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12};
|
|
|
|
/*
|
|
int nBRunLengthToMakeUpCodeL[41] ={
|
|
0x0000, 0x03c0, 0x0c80, 0x0c90, 0x05b0, 0x0330, 0x0340, 0x0350, 0x0360,
|
|
0x0368, 0x0250, 0x0258, 0x0260, 0x0268, 0x0390, 0x0398, 0x03a0,
|
|
0x03a8, 0x03b0, 0x03b8, 0x0290, 0x0298, 0x02a0, 0x02a8, 0x02d0,
|
|
0x02d8, 0x0320, 0x0328, 0x0100, 0x0180, 0x01a0, 0x0120, 0x0130,
|
|
0x0140, 0x0150, 0x0160, 0x0170, 0x01c0, 0x01d0, 0x01e0, 0x01f0};
|
|
*/
|
|
|
|
int nBRunLengthToMakeUpCodeR[41] ={
|
|
0x0000, 0x000f, 0x00c8, 0x00c9, 0x005b, 0x0033, 0x0034, 0x0035, 0x006c,
|
|
0x006d, 0x004a, 0x004b, 0x004c, 0x004d, 0x0072, 0x0073, 0x0074,
|
|
0x0075, 0x0076, 0x0077, 0x0052, 0x0053, 0x0054, 0x0055, 0x005a,
|
|
0x005b, 0x0064, 0x0065, 0x0008, 0x000c, 0x000d, 0x0012, 0x0013,
|
|
0x0014, 0x0015, 0x0016, 0x0017, 0x001c, 0x001d, 0x001e, 0x001f};
|
|
|
|
int nBRunLengthToMakeUpCodeLength[41] ={
|
|
0, 10, 12, 12, 12, 12, 12, 12, 13,
|
|
13, 13, 13, 13, 13, 13, 13, 13,
|
|
13, 13, 13, 13, 13, 13, 13, 13,
|
|
13, 13, 13, 11, 11, 11, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12};
|
|
|
|
int nWRunLengthToTermCodeR[64] ={
|
|
0x0035, 0x0007, 0x0007, 0x0008, 0x000b, 0x000c, 0x000e, 0x000f,
|
|
0x0013, 0x0014, 0x0007, 0x0008, 0x0008, 0x0003, 0x0034, 0x0035,
|
|
0x002a, 0x002b, 0x0027, 0x000c, 0x0008, 0x0017, 0x0003, 0x0004,
|
|
0x0028, 0x002b, 0x0013, 0x0024, 0x0018, 0x0002, 0x0003, 0x001a,
|
|
0x001b, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0028,
|
|
0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x0004, 0x0005, 0x000a,
|
|
0x000b, 0x0052, 0x0053, 0x0054, 0x0055, 0x0024, 0x0025, 0x0058,
|
|
0x0059, 0x005a, 0x005b, 0x004a, 0x004b, 0x0032, 0x0033, 0x0034};
|
|
|
|
int nWRunLengthToTermCodeLength[64] ={
|
|
8, 6, 4, 4, 4, 4, 4, 4,
|
|
5, 5, 5, 5, 6, 6, 6, 6,
|
|
6, 6, 7, 7, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 8, 8};
|
|
|
|
|
|
int nBRunLengthToTermCodeR[64] ={
|
|
0x0037, 0x0002, 0x0003, 0x0002, 0x0003, 0x0003, 0x0002, 0x0003,
|
|
0x0005, 0x0004, 0x0004, 0x0005, 0x0007, 0x0004, 0x0007, 0x0018,
|
|
0x0017, 0x0018, 0x0008, 0x0067, 0x0068, 0x006c, 0x0037, 0x0028,
|
|
0x0017, 0x0018, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x0068, 0x0069,
|
|
0x006a, 0x006b, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
|
|
0x006c, 0x006d, 0x00da, 0x00db, 0x0054, 0x0055, 0x0056, 0x0057,
|
|
0x0064, 0x0065, 0x0052, 0x0053, 0x0024, 0x0037, 0x0038, 0x0027,
|
|
0x0028, 0x0058, 0x0059, 0x002b, 0x002c, 0x005a, 0x0066, 0x0067};
|
|
|
|
int nBRunLengthToTermCodeLength[64] ={
|
|
10, 3, 2, 2, 3, 4, 4, 5,
|
|
6, 6, 7, 7, 7, 8, 8, 9,
|
|
10, 10, 10, 11, 11, 11, 11, 11,
|
|
11, 11, 12, 12, 12, 12, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12};
|
|
|
|
int nWCodeByte0ToRunLength[256] ={
|
|
-4, -4, 29, 30, 45, 46, 22, 22,
|
|
23, 23, 47, 48, 13, 13, 13, 13,
|
|
20, 20, 33, 34, 35, 36, 37, 38,
|
|
19, 19, 31, 32, 1, 1, 1, 1,
|
|
12, 12, 12, 12, 53, 54, 26, 26,
|
|
39, 40, 41, 42, 43, 44, 21, 21,
|
|
28, 28, 61, 62, 63, 0, 320, 384,
|
|
10, 10, 10, 10, 10, 10, 10, 10,
|
|
11, 11, 11, 11, 11, 11, 11, 11,
|
|
27, 27, 59, 60, -1, -1, 18, 18,
|
|
24, 24, 49, 50, 51, 52, 25, 25,
|
|
55, 56, 57, 58, 192, 192, 192, 192,
|
|
1664,1664,1664,1664, 448, 512, -1, 640,
|
|
576, -1, -1, -1, -1, -1, 256, 256,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
8, 8, 8, 8, 8, 8, 8, 8,
|
|
9, 9, 9, 9, 9, 9, 9, 9,
|
|
16, 16, 16, 16, 17, 17, 17, 17,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
14, 14, 14, 14, 15, 15, 15, 15,
|
|
64, 64, 64, 64, 64, 64, 64, 64,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 7, 7, 7};
|
|
|
|
int nWCodeByte0ToCodeWordLength[256] ={
|
|
4, 4, 8, 8, 8, 8, 7, 7,
|
|
7, 7, 8, 8, 6, 6, 6, 6,
|
|
7, 7, 8, 8, 8, 8, 8, 8,
|
|
7, 7, 8, 8, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 8, 8, 7, 7,
|
|
8, 8, 8, 8, 8, 8, 7, 7,
|
|
7, 7, 8, 8, 8, 8, 8, 8,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
7, 7, 8, 8, 1, 1, 7, 7,
|
|
7, 7, 8, 8, 8, 8, 7, 7,
|
|
8, 8, 8, 8, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 8, 8, 1, 8,
|
|
8, 1, 1, 1, 1, 1, 7, 7,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4};
|
|
|
|
int nWCodeByte1ToRunLength[256] ={
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
1472,1536,1600,1728, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, 704, 768, -9, -9,
|
|
-9, -9, 832, 896, 960,1024,1088,1152,
|
|
1216,1280,1344,1408, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9};
|
|
|
|
int nWCodeByte1ToCodeWordLength[256] ={
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
8, 8, 8, 8, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 8, 8, 0, 0,
|
|
0, 0, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
int nWCodeByte4ToRunLength[256] ={
|
|
-7, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
1792,1792,1984,2048,2112,2176,2240,2304,
|
|
1856,1856,1920,1920,2368,2432,2496,2560,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9};
|
|
|
|
int nWCodeByte4ToCodeWordLength[256] ={
|
|
8, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
7, 7, 8, 8, 8, 8, 8, 8,
|
|
7, 7, 7, 7, 8, 8, 8, 8,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
int nBCodeByte0ToRunLength[256] ={
|
|
-5, -5, -5, -5, 13, -4, -4, 14,
|
|
10, 10, 11, 11, -4, -4, 12, 12,
|
|
9, 9, 9, 9, 8, 8, 8, 8,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2};
|
|
|
|
int nBCodeByte0ToCodeWordLength[256] ={
|
|
5, 5, 5, 5, 8, 4, 4, 8,
|
|
7, 7, 7, 7, 4, 4, 7, 7,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2};
|
|
|
|
int nBCodeByte4ToRunLength[256] ={
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
23, 23, 50, 51, 44, 45, 46, 47,
|
|
57, 58, 61, 256, 16, 16, 16, 16,
|
|
17, 17, 17, 17, 48, 49, 62, 63,
|
|
30, 31, 32, 33, 40, 41, 22, 22,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
15, 15, 15, 15, 15, 15, 15, 15,
|
|
128, 192, 26, 27, 28, 29, 19, 19,
|
|
20, 20, 34, 35, 36, 37, 38, 39,
|
|
21, 21, 42, 43, 0, 0, 0, 0,
|
|
12, 12, 12, 12, 12, 12, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12,
|
|
12, 12, 12, 12, 12, 12, 12, 12};
|
|
|
|
int nBCodeByte4ToCodeWordLength[256] ={
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
7, 7, 8, 8, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 8, 8, 8, 8,
|
|
8, 8, 8, 8, 8, 8, 7, 7,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
8, 8, 8, 8, 8, 8, 7, 7,
|
|
7, 7, 8, 8, 8, 8, 8, 8,
|
|
7, 7, 8, 8, 6, 6, 6, 6,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
int nBCodeByte5ToRunLength[256] ={
|
|
-7, -7, -7, -7, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
1792, 1792, 1792, 1792, 1984, 1984, 2048, 2048,
|
|
2112, 2112, 2176, 2176, 2240, 2240, 2304, 2304,
|
|
1856, 1856, 1856, 1856, 1920, 1920, 1920, 1920,
|
|
2368, 2368, 2432, 2432, 2496, 2496, 2560, 2560,
|
|
18, 18, 18, 18, 18, 18, 18, 18,
|
|
52, 52, 640, 704, 768, 832, 55, 55,
|
|
56, 56, 1280, 1344, 1408, 1472, 59, 59,
|
|
60, 60, 1536, 1600, 24, 24, 24, 24,
|
|
25, 25, 25, 25, 1664, 1728, 320, 320,
|
|
384, 384, 448, 448, 512, 576, 53, 53,
|
|
54, 54, 896, 960, 1024, 1088, 1152, 1216,
|
|
64, 64, 64, 64, 64, 64, 64, 64,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9,
|
|
-9, -9, -9, -9, -9, -9, -9, -9};
|
|
|
|
int nBCodeByte5ToCodeWordLength[256] ={
|
|
7, 7, 7, 7, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
6, 6, 6, 6, 7, 7, 7, 7,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
7, 7, 7, 7, 7, 7, 7, 7,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
7, 7, 8, 8, 8, 8, 7, 7,
|
|
7, 7, 8, 8, 8, 8, 7, 7,
|
|
7, 7, 8, 8, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 8, 8, 7, 7,
|
|
7, 7, 7, 7, 8, 8, 7, 7,
|
|
7, 7, 8, 8, 8, 8, 8, 8,
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
|
|
int nRunLengthTo1Bits[9] ={
|
|
0x000, 0x080, 0x0c0, 0x0e0, 0x0f0, 0x0f8, 0x0fc, 0x0fe, 0x0ff};
|
|
|
|
int nRunLengthTo0Bits[9] ={
|
|
0x0ff, 0x07f, 0x03f, 0x01f, 0x00f, 0x007, 0x003, 0x001, 0x000};
|
|
|
|
int nRunLengthTo1BitsR[9] ={
|
|
0x000, 0x001, 0x003, 0x007, 0x00f, 0x01f, 0x03f, 0x07f, 0x0ff};
|
|
|
|
int nRunLengthTo0BitsR[9] ={
|
|
0x0ff, 0x0fe, 0x0fc, 0x0f8, 0x0f0, 0x0e0, 0x0c0, 0x080, 0x000};
|
|
|
|
int n2DCodeByteToState[256] ={
|
|
9, -9, -9, -9, 8, 8, 5, 5,
|
|
7, 7, 7, 7, 4, 4, 4, 4,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
6, 6, 6, 6, 6, 6, 6, 6,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2};
|
|
|
|
int nReverseBits[256] ={
|
|
0x000, 0x080, 0x040, 0x0c0, 0x020, 0x0a0, 0x060, 0x0e0,
|
|
0x010, 0x090, 0x050, 0x0d0, 0x030, 0x0b0, 0x070, 0x0f0,
|
|
0x008, 0x088, 0x048, 0x0c8, 0x028, 0x0a8, 0x068, 0x0e8,
|
|
0x018, 0x098, 0x058, 0x0d8, 0x038, 0x0b8, 0x078, 0x0f8,
|
|
0x004, 0x084, 0x044, 0x0c4, 0x024, 0x0a4, 0x064, 0x0e4,
|
|
0x014, 0x094, 0x054, 0x0d4, 0x034, 0x0b4, 0x074, 0x0f4,
|
|
0x00c, 0x08c, 0x04c, 0x0cc, 0x02c, 0x0ac, 0x06c, 0x0ec,
|
|
0x01c, 0x09c, 0x05c, 0x0dc, 0x03c, 0x0bc, 0x07c, 0x0fc,
|
|
0x002, 0x082, 0x042, 0x0c2, 0x022, 0x0a2, 0x062, 0x0e2,
|
|
0x012, 0x092, 0x052, 0x0d2, 0x032, 0x0b2, 0x072, 0x0f2,
|
|
0x00a, 0x08a, 0x04a, 0x0ca, 0x02a, 0x0aa, 0x06a, 0x0ea,
|
|
0x01a, 0x09a, 0x05a, 0x0da, 0x03a, 0x0ba, 0x07a, 0x0fa,
|
|
0x006, 0x086, 0x046, 0x0c6, 0x026, 0x0a6, 0x066, 0x0e6,
|
|
0x016, 0x096, 0x056, 0x0d6, 0x036, 0x0b6, 0x076, 0x0f6,
|
|
0x00e, 0x08e, 0x04e, 0x0ce, 0x02e, 0x0ae, 0x06e, 0x0ee,
|
|
0x01e, 0x09e, 0x05e, 0x0de, 0x03e, 0x0be, 0x07e, 0x0fe,
|
|
0x001, 0x081, 0x041, 0x0c1, 0x021, 0x0a1, 0x061, 0x0e1,
|
|
0x011, 0x091, 0x051, 0x0d1, 0x031, 0x0b1, 0x071, 0x0f1,
|
|
0x009, 0x089, 0x049, 0x0c9, 0x029, 0x0a9, 0x069, 0x0e9,
|
|
0x019, 0x099, 0x059, 0x0d9, 0x039, 0x0b9, 0x079, 0x0f9,
|
|
0x005, 0x085, 0x045, 0x0c5, 0x025, 0x0a5, 0x065, 0x0e5,
|
|
0x015, 0x095, 0x055, 0x0d5, 0x035, 0x0b5, 0x075, 0x0f5,
|
|
0x00d, 0x08d, 0x04d, 0x0cd, 0x02d, 0x0ad, 0x06d, 0x0ed,
|
|
0x01d, 0x09d, 0x05d, 0x0dd, 0x03d, 0x0bd, 0x07d, 0x0fd,
|
|
0x003, 0x083, 0x043, 0x0c3, 0x023, 0x0a3, 0x063, 0x0e3,
|
|
0x013, 0x093, 0x053, 0x0d3, 0x033, 0x0b3, 0x073, 0x0f3,
|
|
0x00b, 0x08b, 0x04b, 0x0cb, 0x02b, 0x0ab, 0x06b, 0x0eb,
|
|
0x01b, 0x09b, 0x05b, 0x0db, 0x03b, 0x0bb, 0x07b, 0x0fb,
|
|
0x007, 0x087, 0x047, 0x0c7, 0x027, 0x0a7, 0x067, 0x0e7,
|
|
0x017, 0x097, 0x057, 0x0d7, 0x037, 0x0b7, 0x077, 0x0f7,
|
|
0x00f, 0x08f, 0x04f, 0x0cf, 0x02f, 0x0af, 0x06f, 0x0ef,
|
|
0x01f, 0x09f, 0x05f, 0x0df, 0x03f, 0x0bf, 0x07f, 0x0ff};
|
|
|
|
int nFirstOneBit[256] ={
|
|
8, 7, 6, 6, 5, 5, 5, 5,
|
|
4, 4, 4, 4, 4, 4, 4, 4,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
3, 3, 3, 3, 3, 3, 3, 3,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
2, 2, 2, 2, 2, 2, 2, 2,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0,
|
|
0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
|
|
|
|
|
|
/*
|
|
0000 0
|
|
0000 1
|
|
0001 0
|
|
0001 1
|
|
0010 0
|
|
0010 1
|
|
0011 0
|
|
0011 1
|
|
0100 0
|
|
0100 1
|
|
0101 0
|
|
0101 1
|
|
0110 0
|
|
0110 1
|
|
0111 0
|
|
0111 1
|
|
1000 0
|
|
1000 1
|
|
1001 0
|
|
1001 1
|
|
1010 0
|
|
1010 1
|
|
1011 0
|
|
1011 1
|
|
1100 0
|
|
1100 1
|
|
1101 0
|
|
1101 1
|
|
1110 0
|
|
1110 1
|
|
1111 0
|
|
1111 1
|
|
*/
|
|
|
|
/*
|
|
00000000 00000001 00000010 00000011 00000100 00000101 00000110 00000111
|
|
00001000 00001001 00001010 00001011 00001100 00001101 00001110 00001111
|
|
00010000 00010001 00010010 00010011 00010100 00010101 00010110 00010111
|
|
00011000 00011001 00011010 00011011 00011100 00011101 00011110 00011111
|
|
00100000 00100001 00100010 00100011 00100100 00100101 00100110 00100111
|
|
00101000 00101001 00101010 00101011 00101100 00101101 00101110 00101111
|
|
00110000 00110001 00110010 00110011 00110100 00110101 00110110 00110111
|
|
00111000 00111001 00111010 00111011 00111100 00111101 00111110 00111111
|
|
|
|
01000000 01000001 01000010 01000011 01000100 01000101 01000110 01000111
|
|
01001000 01001001 01001010 01001011 01001100 01001101 01001110 01001111
|
|
01010000 01010001 01010010 01010011 01010100 01010101 01010110 01010111
|
|
01011000 01011001 01011010 01011011 01011100 01011101 01011110 01011111
|
|
01100000 01100001 01100010 01100011 01100100 01100101 01100110 01100111
|
|
01101000 01101001 01101010 01101011 01101100 01101101 01101110 01101111
|
|
01110000 01110001 01110010 01110011 01110100 01110101 01110110 01110111
|
|
01111000 01111001 01111010 01111011 01111100 01111101 01111110 01111111
|
|
|
|
10000000 10000001 10000010 10000011 10000100 10000101 10000110 10000111
|
|
10001000 10001001 10001010 10001011 10001100 10001101 10001110 10001111
|
|
10010000 10010001 10010010 10010011 10010100 10010101 10010110 10010111
|
|
10011000 10011001 10011010 10011011 10011100 10011101 10011110 10011111
|
|
10100000 10100001 10100010 10100011 10100100 10100101 10100110 10100111
|
|
10101000 10101001 10101010 10101011 10101100 10101101 10101110 10101111
|
|
10110000 10110001 10110010 10110011 10110100 10110101 10110110 10110111
|
|
10111000 10111001 10111010 10111011 10111100 10111101 10111110 10111111
|
|
|
|
11000000 11000001 11000010 11000011 11000100 11000101 11000110 11000111
|
|
11001000 11001001 11001010 11001011 11001100 11001101 11001110 11001111
|
|
11010000 11010001 11010010 11010011 11010100 11010101 11010110 11010111
|
|
11011000 11011001 11011010 11011011 11011100 11011101 11011110 11011111
|
|
11100000 11100001 11100010 11100011 11100100 11100101 11100110 11100111
|
|
11101000 11101001 11101010 11101011 11101100 11101101 11101110 11101111
|
|
11110000 11110001 11110010 11110011 11110100 11110101 11110110 11110111
|
|
11111000 11111001 11111010 11111011 11111100 11111101 11111110 11111111
|
|
*/
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CompressImage
|
|
|
|
PURPOSE: This routine compresses the image.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI CompressImage(int nWidthPixels, int nWidthBytes, int nHeight,
|
|
PBYTE pImageData, int nImageType, PBYTE *ppCompressedBuffer,
|
|
PINT pnCompressedBufferSize, int nCompressionType, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
|
|
switch (nCompressionType){
|
|
case FIO_0D: /* Uncompressed coding */
|
|
CheckError2( Compress0D(nWidthPixels, nHeight, pImageData,
|
|
ppCompressedBuffer, pnCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_1D: /* CCITT Group 3 1d coding */
|
|
CheckError2( CompressG31D(nWidthPixels, nHeight, pImageData,
|
|
ppCompressedBuffer, pnCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_2D: /* CCITT Group 4 2d coding */
|
|
CheckError2( CompressG42D(nWidthPixels, nHeight, pImageData,
|
|
ppCompressedBuffer, pnCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_PACKED: /* PackBits coding */
|
|
CheckError2( CompressPackBits(nWidthPixels, nHeight, pImageData,
|
|
ppCompressedBuffer, pnCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_LZW: /* LZW coding */
|
|
CheckError2( CompressLZW(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
nImageType, ppCompressedBuffer, pnCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_1D2D: /* CCITT Group 3 2d coding */
|
|
default:
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: DecompressImage
|
|
|
|
PURPOSE: This routine decompresses the image.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI DecompressImage(int nWidthPixels, int nWidthBytes, int nHeight,
|
|
PBYTE pImageData, int nImageType, PBYTE pCompressedBuffer,
|
|
int nCompressedBufferSize, int nCompressionType, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
|
|
switch (nCompressionType){
|
|
case FIO_0D: /* Uncompressed coding */
|
|
CheckError2( Decompress0D(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
pCompressedBuffer, nCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_1D: /* CCITT Group 3 1d coding */
|
|
CheckError2( DecompressG31D(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
pCompressedBuffer, nCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_1D2D: /* CCITT Group 3 2d coding */
|
|
CheckError2( DecompressG32D(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
pCompressedBuffer, nCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_2D: /* CCITT Group 4 2d coding */
|
|
CheckError2( DecompressG42D(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
pCompressedBuffer, nCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
case FIO_PACKED: /* PackBits coding */
|
|
if (nStatus = DecompressPackBits(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
pCompressedBuffer, nCompressedBufferSize, nFlags)){
|
|
nFlags &= ~COMPRESS_COMPRESSED_IS_LTR;
|
|
CheckError2( DecompressPackBits(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
pCompressedBuffer, nCompressedBufferSize, nFlags))
|
|
}
|
|
break;
|
|
|
|
case FIO_LZW: /* LZW coding */
|
|
CheckError2( DecompressLZW(nWidthPixels, nHeight, nWidthBytes, pImageData,
|
|
nImageType, pCompressedBuffer, nCompressedBufferSize, nFlags))
|
|
break;
|
|
|
|
default:
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: ReverseBits
|
|
|
|
PURPOSE: This routine reverses the bit orders within the bytes of a buffer.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI ReverseBits(PBYTE pBuffer, int nSize){
|
|
|
|
int nStatus = 0;
|
|
int nLoop;
|
|
|
|
|
|
for (nLoop = nSize >> 4; nLoop; nLoop--){
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
}
|
|
for (nLoop = (nSize >> 2) & 3; nLoop; nLoop--){
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
}
|
|
for (nLoop = nSize & 3; nLoop; nLoop--){
|
|
*(pBuffer++) = nReverseBits[*pBuffer];
|
|
}
|
|
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: NegateBits
|
|
|
|
PURPOSE: This routine negates the bits within the bytes of a buffer.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI NegateBits(PBYTE pBuffer, int nSize){
|
|
|
|
int nStatus = 0;
|
|
int nLoop;
|
|
PLONG pLong;
|
|
|
|
|
|
nLoop = min(nSize, (int)sizeof(LONG) - (((int)pBuffer) & 3 ));
|
|
nSize -= nLoop;
|
|
for (; nLoop; nLoop--){
|
|
*(pBuffer++) ^= 0x0ff;
|
|
}
|
|
|
|
pLong = (PLONG) pBuffer;
|
|
for (nLoop = nSize >> 5; nLoop; nLoop--){
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
}
|
|
for (nLoop = (nSize >> 2) & 7; nLoop; nLoop--){
|
|
*(pLong++) ^= 0x0ffffffff;
|
|
}
|
|
|
|
pBuffer = (PBYTE) pLong;
|
|
for (nLoop = nSize & 3; nLoop; nLoop--){
|
|
*(pBuffer++) ^= 0x0ff;
|
|
}
|
|
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: LineToPackBits
|
|
|
|
PURPOSE: This routine compresses a line of image data using PackBits.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI LineToPackBits(PBYTE pImageData, PBYTE *ppCompressedBuffer,
|
|
int nWidthBytes){
|
|
|
|
int nStatus = 0;
|
|
|
|
int nLoop;
|
|
int nByte;
|
|
PBYTE pCompressedBuffer;
|
|
int nLoopEnd;
|
|
|
|
|
|
pCompressedBuffer = *ppCompressedBuffer;
|
|
while(nWidthBytes){
|
|
nLoopEnd = min(127, nWidthBytes);
|
|
nByte = pImageData[0];
|
|
for (nLoop = 1; nLoop < nLoopEnd; nLoop++){
|
|
if (nByte != pImageData[nLoop]){
|
|
break;
|
|
}
|
|
}
|
|
if (nLoop > 2){ // We have a run.
|
|
*(pCompressedBuffer++) = (nLoop - 2) ^ 0x0ff;
|
|
*(pCompressedBuffer++) = nByte;
|
|
nWidthBytes -= nLoop;
|
|
pImageData += nLoop;
|
|
continue;
|
|
}
|
|
// Literal.
|
|
for (nLoop = 1; nLoop < nLoopEnd; nLoop++){
|
|
nByte = pImageData[nLoop];
|
|
if ((nByte != pImageData[nLoop + 1]) || (nByte != pImageData[nLoop + 2])){
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
nWidthBytes -= nLoop;
|
|
*(pCompressedBuffer++) = nLoop - 1;
|
|
for (; nLoop; nLoop--){
|
|
*(pCompressedBuffer++) = *(pImageData++);
|
|
}
|
|
}
|
|
*ppCompressedBuffer = pCompressedBuffer;
|
|
|
|
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CompressPackBits
|
|
|
|
PURPOSE: This routine compresses the image data using PackBits.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI CompressPackBits(int nWidth, int nHeight, PBYTE pImageData,
|
|
PBYTE *ppCompressedBuffer, PINT pnCompressedBufferSize,
|
|
int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nLine;
|
|
int nWidthBytes;
|
|
PBYTE pCompressedBufferStart;
|
|
PBYTE pCompressedBuffer;
|
|
int nCompressedBufferMaxSize;
|
|
BOOL bReverseImage = FALSE;
|
|
BOOL bNegateImage = FALSE;
|
|
|
|
|
|
nWidthBytes = (nWidth + 7) >> 3;
|
|
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
bNegateImage = TRUE;
|
|
CheckError2( NegateBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
if (!(nFlags & COMPRESS_EXPANDED_IS_LTR)){
|
|
bReverseImage = TRUE;
|
|
CheckError2( ReverseBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
|
|
nCompressedBufferMaxSize = (nHeight * nWidthBytes) << 2;
|
|
if (!(pCompressedBufferStart = VirtualAlloc(NULL, nCompressedBufferMaxSize,
|
|
MEM_COMMIT, PAGE_READWRITE))){
|
|
nStatus = Error(DISPLAY_CANTALLOC);
|
|
goto Exit;
|
|
}
|
|
pCompressedBuffer = pCompressedBufferStart;
|
|
|
|
for (nLine = 0; nLine < nHeight; nLine++){
|
|
CheckError2( LineToPackBits(pImageData + (nLine * nWidthBytes),
|
|
&pCompressedBuffer, nWidthBytes))
|
|
}
|
|
|
|
nCompressedBufferMaxSize = (pCompressedBuffer - pCompressedBufferStart) + 4;
|
|
// if (nStatus = ReAllocateMemory(nCompressedBufferMaxSize, &pCompressedBufferStart, NO_INIT)){
|
|
// goto Exit;
|
|
// }
|
|
*ppCompressedBuffer = pCompressedBufferStart;
|
|
*pnCompressedBufferSize = nCompressedBufferMaxSize - 4;
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBufferStart, nCompressedBufferMaxSize - 4))
|
|
}
|
|
|
|
|
|
Exit:
|
|
if (bReverseImage){
|
|
ReverseBits(pImageData, nWidthBytes * nHeight);
|
|
}
|
|
if (bNegateImage){
|
|
NegateBits(pImageData, nWidthBytes * nHeight);
|
|
}
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: DecompressPackBits
|
|
|
|
PURPOSE: This routine decompresses the image data using PackBits.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI DecompressPackBits(int nWidth, int nHeight, int nWidthBytes, PBYTE pImageData,
|
|
PBYTE pCompressedBuffer, int nCompressedBufferSize, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nLine;
|
|
int nByteIndex;
|
|
int nCount;
|
|
int nByte;
|
|
PBYTE pImageData2;
|
|
|
|
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBuffer, nCompressedBufferSize))
|
|
}
|
|
|
|
pImageData2 = pImageData;
|
|
for (nLine = 0; nLine < nHeight; nLine++){
|
|
for (nByteIndex = nWidthBytes; nByteIndex > 0;){
|
|
nCount = *(pCompressedBuffer++);
|
|
if (nCount < 128){ // Literal string.
|
|
nCount++;
|
|
nByteIndex -= nCount;
|
|
for (; nCount; nCount--){
|
|
*(pImageData2++) = *(pCompressedBuffer++);
|
|
}
|
|
}else if (nCount > 128){ // Encoded string.
|
|
nCount = (nCount ^ 0x0ff) + 2;
|
|
nByteIndex -= nCount;
|
|
nByte = *(pCompressedBuffer++);
|
|
for (; nCount; nCount--){
|
|
*(pImageData2++) = nByte;
|
|
}
|
|
}else{ // noop.
|
|
continue;
|
|
}
|
|
}
|
|
if (nByteIndex != 0){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
CheckError2( NegateBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
if (!(nFlags & COMPRESS_EXPANDED_IS_LTR)){
|
|
CheckError2( ReverseBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: RunLengthsTo1DLine
|
|
|
|
PURPOSE: This routine compresses the image data using Group 3 1D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI RunLengthsTo1DLine(PINT pnRunLengths, PBYTE *ppCompressedBuffer,
|
|
PUINT puCodeWord, PINT pnCodeWordBits,
|
|
int nWidthBytes, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
int nRunLengthIndex;
|
|
int nRunLength;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
int nIndex;
|
|
PBYTE pCompressedBuffer;
|
|
|
|
|
|
uCodeWord = *puCodeWord;
|
|
nCodeWordBits = *pnCodeWordBits;
|
|
pCompressedBuffer = *ppCompressedBuffer;
|
|
|
|
// Translate Runlengths into Codewords.
|
|
// Labels use Prefix = C1D (Compress 1D), Suffix = W or B (White or Black).
|
|
|
|
if (nFlags & COMPRESS_BEGINNING_EOLS){
|
|
uCodeWord = (uCodeWord << 12) | 0x01;
|
|
nCodeWordBits += 12;
|
|
}
|
|
|
|
if (!pnRunLengths[0]){
|
|
uCodeWord = (uCodeWord << 8) | 0x35;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
nRunLengthIndex = 1;
|
|
goto C1DB;
|
|
}else{
|
|
nRunLengthIndex = 0;
|
|
}
|
|
|
|
C1DW:
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
if (!(nRunLength = pnRunLengths[nRunLengthIndex++])){
|
|
goto C1DDone;
|
|
}
|
|
while(nRunLength > 63){
|
|
nIndex = min(40, nRunLength >> 6);
|
|
uCodeWord = (uCodeWord << nWRunLengthToMakeUpCodeLength[nIndex])
|
|
| nWRunLengthToMakeUpCodeR[nIndex];
|
|
nCodeWordBits += nWRunLengthToMakeUpCodeLength[nIndex];
|
|
nRunLength -= nIndex << 6;
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
}
|
|
uCodeWord = (uCodeWord << nWRunLengthToTermCodeLength[nRunLength])
|
|
| nWRunLengthToTermCodeR[nRunLength];
|
|
nCodeWordBits += nWRunLengthToTermCodeLength[nRunLength];
|
|
|
|
C1DB:
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
if (!(nRunLength = pnRunLengths[nRunLengthIndex++])){
|
|
goto C1DDone;
|
|
}
|
|
while(nRunLength > 63){
|
|
nIndex = min(40, nRunLength >> 6);
|
|
uCodeWord = (uCodeWord << nBRunLengthToMakeUpCodeLength[nIndex])
|
|
| nBRunLengthToMakeUpCodeR[nIndex];
|
|
nCodeWordBits += nBRunLengthToMakeUpCodeLength[nIndex];
|
|
nRunLength -= nIndex << 6;
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
}
|
|
uCodeWord = (uCodeWord << nBRunLengthToTermCodeLength[nRunLength])
|
|
| nBRunLengthToTermCodeR[nRunLength];
|
|
nCodeWordBits += nBRunLengthToTermCodeLength[nRunLength];
|
|
goto C1DW;
|
|
|
|
|
|
C1DDone:
|
|
if ((nFlags & COMPRESS_BYTE_ALIGN_LINES) && (nFlags & COMPRESS_ENDING_EOLS)){
|
|
uCodeWord = (uCodeWord << (24 - nCodeWordBits)) | 0x001;
|
|
nCodeWordBits = 24;
|
|
}else if (nFlags & COMPRESS_BYTE_ALIGN_LINES){ // && !bAddEndingEols
|
|
if (nCodeWordBits){
|
|
uCodeWord <<= 8 - nCodeWordBits;
|
|
nCodeWordBits = 8;
|
|
}
|
|
}else if (nFlags & COMPRESS_ENDING_EOLS){ // && !bByteAlignLines
|
|
uCodeWord = (uCodeWord << 12) | 0x001;
|
|
nCodeWordBits += 12;
|
|
}
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
|
|
*puCodeWord = uCodeWord;
|
|
*pnCodeWordBits = nCodeWordBits;
|
|
*ppCompressedBuffer = pCompressedBuffer;
|
|
|
|
|
|
//Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: RunLengthsTo2DLine
|
|
|
|
PURPOSE: This routine compresses the image data using Group 3 1D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI RunLengthsTo2DLine(PINT pnRunLengths, PINT pnOldRunLengths,
|
|
PBYTE *ppCompressedBuffer, PUINT puCodeWord,
|
|
PINT pnCodeWordBits, int nWidthBytes, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
int nIndex;
|
|
int nRunLength;
|
|
int nLoop;
|
|
PBYTE pCompressedBuffer;
|
|
|
|
int nOldRunLength;
|
|
int nB1;
|
|
int nB2;
|
|
int nOldRunLenthIndex;
|
|
int nOldRunLenthLastIndex;
|
|
|
|
int nA1; // Run length left till A1.
|
|
int nA1Index;
|
|
|
|
|
|
uCodeWord = *puCodeWord;
|
|
nCodeWordBits = *pnCodeWordBits;
|
|
pCompressedBuffer = *ppCompressedBuffer;
|
|
|
|
// Translate Runlengths into Codewords.
|
|
// Labels use Prefix = C2D (Compress 2D), Suffix = W or B (White or Black).
|
|
|
|
if (nFlags & COMPRESS_BEGINNING_EOLS){
|
|
uCodeWord = (uCodeWord << 12) | 0x01;
|
|
nCodeWordBits += 12;
|
|
}
|
|
|
|
// Set the Runlength after the last one to 99,999 to force it out of the calculations.
|
|
// There is no body to this for loop.
|
|
for (nOldRunLenthLastIndex = 1; pnOldRunLengths[nOldRunLenthLastIndex]
|
|
&& pnOldRunLengths[nOldRunLenthLastIndex] != 99999; nOldRunLenthLastIndex++);
|
|
pnOldRunLengths[nOldRunLenthLastIndex ] = 99999;
|
|
pnOldRunLengths[nOldRunLenthLastIndex + 1] = 99999;
|
|
pnOldRunLengths[nOldRunLenthLastIndex + 2] = 99999;
|
|
pnOldRunLengths[nOldRunLenthLastIndex + 3] = 99999;
|
|
|
|
nOldRunLength = pnOldRunLengths[0];
|
|
nOldRunLenthIndex = 1;
|
|
|
|
nA1 = pnRunLengths[0];
|
|
nA1Index = 1;
|
|
nRunLength = 0;
|
|
goto C2DStart;
|
|
|
|
C2DNext:
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
if (!nA1){
|
|
goto C2DDone;
|
|
}
|
|
|
|
nOldRunLength -= nRunLength;
|
|
while(nOldRunLength <= 0){
|
|
nOldRunLength += pnOldRunLengths[nOldRunLenthIndex++];
|
|
}
|
|
|
|
C2DStart:
|
|
if ((nOldRunLenthIndex & 1) == (nA1Index & 1)){
|
|
nB1 = nOldRunLength;
|
|
nB2 = nB1 + pnOldRunLengths[nOldRunLenthIndex];
|
|
}else{
|
|
nB1 = nOldRunLength + pnOldRunLengths[nOldRunLenthIndex];
|
|
nB2 = nB1 + pnOldRunLengths[nOldRunLenthIndex + 1];
|
|
}
|
|
|
|
|
|
switch ((nA1 - nB1) + 3){
|
|
case 0: // A1 = B1 - 3.
|
|
uCodeWord = (uCodeWord << 7) | 0x02;
|
|
nCodeWordBits += 7;
|
|
nRunLength = nA1;
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
case 1: // A1 = B1 - 2.
|
|
uCodeWord = (uCodeWord << 6) | 0x02;
|
|
nCodeWordBits += 6;
|
|
nRunLength = nA1;
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
case 2: // A1 = B1 - 1.
|
|
uCodeWord = (uCodeWord << 3) | 0x02;
|
|
nCodeWordBits += 3;
|
|
nRunLength = nA1;
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
case 3: // A1 = B1.
|
|
uCodeWord = (uCodeWord << 1) | 0x1;
|
|
nCodeWordBits += 1;
|
|
nRunLength = nA1;
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
case 4: // A1 = B1 + 1.
|
|
uCodeWord = (uCodeWord << 3) | 0x03;
|
|
nCodeWordBits += 3;
|
|
nRunLength = nA1;
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
case 5: // A1 = B1 + 2.
|
|
uCodeWord = (uCodeWord << 6) | 0x03;
|
|
nCodeWordBits += 6;
|
|
nRunLength = nA1;
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
case 6: // A1 = B1 + 3.
|
|
uCodeWord = (uCodeWord << 7) | 0x03;
|
|
nCodeWordBits += 7;
|
|
nRunLength = nA1;
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
|
|
default: // Pass or Horz mode.
|
|
if (nB2 < nA1){
|
|
// Check to see if there will be 3 or more passes.
|
|
if (!(nOldRunLenthIndex & 1)){
|
|
nIndex = nOldRunLenthIndex + 1;
|
|
}else{
|
|
nIndex = nOldRunLenthIndex + 2;
|
|
}
|
|
nRunLength = nB2;
|
|
for (nLoop = 0; nLoop < 3 && nRunLength < nA1; nLoop++){
|
|
nRunLength += pnOldRunLengths[nIndex++];
|
|
nRunLength += pnOldRunLengths[nIndex++];
|
|
}
|
|
if (nLoop < 3){
|
|
// Pass mode.
|
|
uCodeWord = (uCodeWord << 4) | 0x01;
|
|
nCodeWordBits += 4;
|
|
nRunLength = nB2;
|
|
nA1 -= nRunLength;
|
|
goto C2DNext;
|
|
}
|
|
}
|
|
|
|
// Horizontal mode.
|
|
uCodeWord = (uCodeWord << 3) | 0x001;
|
|
nCodeWordBits += 3;
|
|
nRunLength = nA1;
|
|
|
|
if ((nA1Index & 1)){
|
|
// nA1 is a white run length;
|
|
while(nA1 > 63){
|
|
nIndex = min(40, nA1 >> 6);
|
|
uCodeWord = (uCodeWord << nWRunLengthToMakeUpCodeLength[nIndex])
|
|
| nWRunLengthToMakeUpCodeR[nIndex];
|
|
nCodeWordBits += nWRunLengthToMakeUpCodeLength[nIndex];
|
|
nA1 -= nIndex << 6;
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
}
|
|
uCodeWord = (uCodeWord << nWRunLengthToTermCodeLength[nA1])
|
|
| nWRunLengthToTermCodeR[nA1];
|
|
nCodeWordBits += nWRunLengthToTermCodeLength[nA1];
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
nRunLength += nA1;
|
|
while(nA1 > 63){
|
|
nIndex = min(40, nA1 >> 6);
|
|
uCodeWord = (uCodeWord << nBRunLengthToMakeUpCodeLength[nIndex])
|
|
| nBRunLengthToMakeUpCodeR[nIndex];
|
|
nCodeWordBits += nBRunLengthToMakeUpCodeLength[nIndex];
|
|
nA1 -= nIndex << 6;
|
|
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
}
|
|
uCodeWord = (uCodeWord << nBRunLengthToTermCodeLength[nA1])
|
|
| nBRunLengthToTermCodeR[nA1];
|
|
nCodeWordBits += nBRunLengthToTermCodeLength[nA1];
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
}else{
|
|
// nA1 is a black run length;
|
|
while(nA1 > 63){
|
|
nIndex = min(40, nA1 >> 6);
|
|
uCodeWord = (uCodeWord << nBRunLengthToMakeUpCodeLength[nIndex])
|
|
| nBRunLengthToMakeUpCodeR[nIndex];
|
|
nCodeWordBits += nBRunLengthToMakeUpCodeLength[nIndex];
|
|
nA1 -= nIndex << 6;
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
}
|
|
uCodeWord = (uCodeWord << nBRunLengthToTermCodeLength[nA1])
|
|
| nBRunLengthToTermCodeR[nA1];
|
|
nCodeWordBits += nBRunLengthToTermCodeLength[nA1];
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
nRunLength += nA1;
|
|
while(nA1 > 63){
|
|
nIndex = min(40, nA1 >> 6);
|
|
uCodeWord = (uCodeWord << nWRunLengthToMakeUpCodeLength[nIndex])
|
|
| nWRunLengthToMakeUpCodeR[nIndex];
|
|
nCodeWordBits += nWRunLengthToMakeUpCodeLength[nIndex];
|
|
nA1 -= nIndex << 6;
|
|
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
}
|
|
uCodeWord = (uCodeWord << nWRunLengthToTermCodeLength[nA1])
|
|
| nWRunLengthToTermCodeR[nA1];
|
|
nCodeWordBits += nWRunLengthToTermCodeLength[nA1];
|
|
nA1 = pnRunLengths[nA1Index++];
|
|
goto C2DNext;
|
|
}
|
|
}
|
|
|
|
|
|
C2DDone:
|
|
pnOldRunLengths[nOldRunLenthLastIndex ] = 0;
|
|
pnOldRunLengths[nOldRunLenthLastIndex + 1] = 0;
|
|
pnOldRunLengths[nOldRunLenthLastIndex + 2] = 0;
|
|
pnOldRunLengths[nOldRunLenthLastIndex + 3] = 0;
|
|
*puCodeWord = uCodeWord;
|
|
*pnCodeWordBits = nCodeWordBits;
|
|
*ppCompressedBuffer = pCompressedBuffer;
|
|
|
|
|
|
//Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: Compress0D
|
|
|
|
PURPOSE: This routine compresses the image data using nncompressed data.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI Compress0D(int nWidth, int nHeight, PBYTE pImageData,
|
|
PBYTE *ppCompressedBuffer, PINT pnCompressedBufferSize,
|
|
int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nWidthBytes;
|
|
BOOL bReverseImage = FALSE;
|
|
BOOL bNegateImage = FALSE;
|
|
|
|
|
|
nWidthBytes = (nWidth + 7) >> 3;
|
|
|
|
*pnCompressedBufferSize = nWidthBytes * nHeight;
|
|
if (!(*ppCompressedBuffer = VirtualAlloc(NULL, *pnCompressedBufferSize,
|
|
MEM_COMMIT, PAGE_READWRITE))){
|
|
nStatus = Error(DISPLAY_CANTALLOC);
|
|
goto Exit;
|
|
}
|
|
memcpy(*ppCompressedBuffer, pImageData, *pnCompressedBufferSize);
|
|
|
|
if ((!(nFlags & COMPRESS_EXPANDED_IS_LTR) && (nFlags & COMPRESS_COMPRESSED_IS_LTR))
|
|
|| ((nFlags & COMPRESS_EXPANDED_IS_LTR) && !(nFlags & COMPRESS_COMPRESSED_IS_LTR))){
|
|
CheckError2( ReverseBits(*ppCompressedBuffer, *pnCompressedBufferSize))
|
|
}
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
bNegateImage = TRUE;
|
|
CheckError2( NegateBits(*ppCompressedBuffer, *pnCompressedBufferSize))
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CompressG31D
|
|
|
|
PURPOSE: This routine compresses the image data using Group 3 1D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI CompressG31D(int nWidth, int nHeight, PBYTE pImageData,
|
|
PBYTE *ppCompressedBuffer, PINT pnCompressedBufferSize,
|
|
int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nLine;
|
|
int nRunLengths[8000];
|
|
int nWidthBytes;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
PBYTE pCompressedBufferStart;
|
|
PBYTE pCompressedBuffer;
|
|
int nCompressedBufferMaxSize;
|
|
BOOL bReverseImage = FALSE;
|
|
BOOL bNegateImage = FALSE;
|
|
|
|
|
|
nWidthBytes = (nWidth + 7) >> 3;
|
|
uCodeWord = 0;
|
|
nCodeWordBits = 0;
|
|
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
bNegateImage = TRUE;
|
|
CheckError2( NegateBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
|
|
nCompressedBufferMaxSize = max(10000, (nHeight * nWidthBytes) * 6);
|
|
if (!(pCompressedBufferStart = VirtualAlloc(NULL, nCompressedBufferMaxSize,
|
|
MEM_COMMIT, PAGE_READWRITE))){
|
|
nStatus = Error(DISPLAY_CANTALLOC);
|
|
goto Exit;
|
|
}
|
|
pCompressedBuffer = pCompressedBufferStart;
|
|
|
|
for (nLine = 0; nLine < nHeight; nLine++){
|
|
CheckError2( LineToRunLengths(pImageData + (nLine * nWidthBytes),
|
|
&nRunLengths[0], nWidth, nWidthBytes, nFlags))
|
|
CheckError2( RunLengthsTo1DLine(&nRunLengths[0], &pCompressedBuffer,
|
|
&uCodeWord, &nCodeWordBits, nWidthBytes, nFlags))
|
|
}
|
|
// Write last piece of data out.
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
if (nCodeWordBits){
|
|
*(pCompressedBuffer++) = uCodeWord << (8 - nCodeWordBits);
|
|
nCodeWordBits = 0;
|
|
}
|
|
if ((pCompressedBuffer - pCompressedBufferStart) >= nCompressedBufferMaxSize){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
nCompressedBufferMaxSize = (pCompressedBuffer - pCompressedBufferStart) + 4;
|
|
// if (nStatus = ReduceMemory(nCompressedBufferMaxSize, &pCompressedBufferStart)){
|
|
// goto Exit;
|
|
// }
|
|
*ppCompressedBuffer = pCompressedBufferStart;
|
|
*pnCompressedBufferSize = nCompressedBufferMaxSize - 4;
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBufferStart, nCompressedBufferMaxSize - 4))
|
|
}
|
|
|
|
|
|
Exit:
|
|
if (bNegateImage){
|
|
NegateBits(pImageData, nWidthBytes * nHeight);
|
|
}
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CompressG42D
|
|
|
|
PURPOSE: This routine compresses the image data using Group 4 2D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI CompressG42D(int nWidth, int nHeight, PBYTE pImageData,
|
|
PBYTE *ppCompressedBuffer, PINT pnCompressedBufferSize,
|
|
int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nLine;
|
|
int nOldRunLengths[8000];
|
|
int nRunLengths[8000];
|
|
int nWidthBytes;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
int nLoop;
|
|
PBYTE pCompressedBufferStart;
|
|
PBYTE pCompressedBuffer;
|
|
int nCompressedBufferMaxSize;
|
|
BOOL bReverseImage = FALSE;
|
|
BOOL bNegateImage = FALSE;
|
|
|
|
|
|
nWidthBytes = (nWidth + 7) >> 3;
|
|
uCodeWord = 0;
|
|
nCodeWordBits = 0;
|
|
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
bNegateImage = TRUE;
|
|
CheckError2( NegateBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
|
|
// Init to all white line.
|
|
nOldRunLengths[0] = nWidth;
|
|
nOldRunLengths[1] = 0;
|
|
|
|
nCompressedBufferMaxSize = max(10000, (nHeight * nWidthBytes) * 6);
|
|
if (!(pCompressedBufferStart = VirtualAlloc(NULL, nCompressedBufferMaxSize,
|
|
MEM_COMMIT, PAGE_READWRITE))){
|
|
nStatus = Error(DISPLAY_CANTALLOC);
|
|
goto Exit;
|
|
}
|
|
pCompressedBuffer = pCompressedBufferStart;
|
|
|
|
for (nLine = 0; nLine < nHeight; nLine++){
|
|
CheckError2( LineToRunLengths(pImageData + (nLine * nWidthBytes),
|
|
&nRunLengths[0], nWidth, nWidthBytes, nFlags))
|
|
CheckError2( RunLengthsTo2DLine(&nRunLengths[0], &nOldRunLengths[0],
|
|
&pCompressedBuffer, &uCodeWord, &nCodeWordBits, nWidthBytes, nFlags))
|
|
|
|
nOldRunLengths[0] = nRunLengths[0]; // The first entry may be 0.
|
|
for (nLoop = 1; nRunLengths[nLoop]; nLoop++){
|
|
nOldRunLengths[nLoop] = nRunLengths[nLoop];
|
|
}
|
|
nOldRunLengths[nLoop++] = 0;
|
|
nOldRunLengths[nLoop++] = 0;
|
|
nOldRunLengths[nLoop++] = 0;
|
|
nOldRunLengths[nLoop] = 0;
|
|
}
|
|
|
|
uCodeWord = (uCodeWord << 24) | 0x001001;
|
|
nCodeWordBits += 24;
|
|
|
|
while(nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
if (nCodeWordBits > 0){
|
|
*(pCompressedBuffer++) = uCodeWord << (8 - nCodeWordBits);
|
|
}
|
|
|
|
|
|
nCompressedBufferMaxSize = (pCompressedBuffer - pCompressedBufferStart) + 4;
|
|
// if (nStatus = ReduceMemory(nCompressedBufferMaxSize, &pCompressedBufferStart)){
|
|
// goto Exit;
|
|
// }
|
|
*ppCompressedBuffer = pCompressedBufferStart;
|
|
*pnCompressedBufferSize = nCompressedBufferMaxSize - 4;
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBufferStart, nCompressedBufferMaxSize - 4))
|
|
}
|
|
|
|
|
|
Exit:
|
|
if (bNegateImage){
|
|
NegateBits(pImageData, nWidthBytes * nHeight);
|
|
}
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: D1DLineToRunLengths
|
|
|
|
PURPOSE: This routine decompresses the image data using Group 3 1D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI D1DLineToRunLengths(PINT pnRunLengths, PBYTE *ppCompressedBuffer,
|
|
PUINT puCodeWord, PINT pnCodeWordBits,
|
|
int nWidth, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
int nRunLengthIndex;
|
|
int nRunLength;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
int nRunLengthTotal;
|
|
int nCodeWordLength;
|
|
BOOL bEOLReceived;
|
|
int nLoop;
|
|
PBYTE pCompressedBuffer;
|
|
int nShift;
|
|
|
|
|
|
uCodeWord = *puCodeWord;
|
|
nCodeWordBits = *pnCodeWordBits;
|
|
nRunLengthTotal = 0;
|
|
nRunLengthIndex = 0;
|
|
bEOLReceived = FALSE;
|
|
pCompressedBuffer = *ppCompressedBuffer;
|
|
pnRunLengths[0] = 0;
|
|
|
|
|
|
// Translate Codewords into Runlengths.
|
|
// Labels use Prefix = D1D (Decompress 1D), Suffix = W or B (White or Black).
|
|
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
|
|
if (!(uCodeWord >> (CODE_WORD_SHIFT - 3))){
|
|
// Must have an EOL.
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
// nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
// goto Exit;
|
|
// }
|
|
uCodeWord <<= 11;
|
|
nCodeWordBits -= 11;
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
for (nLoop = 0; nLoop < 128; nLoop++){
|
|
if (!(nShift = nFirstOneBit[uCodeWord >> CODE_WORD_SHIFT])){
|
|
break;
|
|
}
|
|
uCodeWord <<= nShift;
|
|
nCodeWordBits -= nShift;
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
}
|
|
if (!(uCodeWord & CODE_WORD_BIT_MASK)){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
uCodeWord <<= 1;
|
|
nCodeWordBits -= 1;
|
|
}
|
|
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
|
|
|
|
D1DW:
|
|
do{
|
|
nRunLength = nWCodeByte0ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte0ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
if (nRunLength == -1){
|
|
nRunLength = nWCodeByte1ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte1ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// }else if (nRunLength == -4){
|
|
}else{
|
|
nRunLength = nWCodeByte4ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte4ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// if (nRunLength == -7){
|
|
// if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
// nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
// goto Exit;
|
|
// }
|
|
nRunLength = nWidth - nRunLengthTotal;
|
|
nRunLengthTotal += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
nRunLength = 0;
|
|
bEOLReceived = TRUE;
|
|
goto D1DDone;
|
|
}
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// }else{
|
|
// nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
// goto Exit;
|
|
}
|
|
}
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
nRunLengthTotal += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
}while(nRunLength >= 64);
|
|
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
if (nRunLengthTotal >= nWidth){
|
|
goto D1DDone;
|
|
}
|
|
|
|
|
|
//D1DB:
|
|
do{
|
|
nRunLength = nBCodeByte0ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte0ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
if (nRunLength == -4){
|
|
nRunLength = nBCodeByte4ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte4ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// }else if (nRunLength == -5){
|
|
}else{
|
|
nRunLength = nBCodeByte5ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte5ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// if (nRunLength == -7){
|
|
// if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
// nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
// goto Exit;
|
|
// }
|
|
nRunLength = nWidth - nRunLengthTotal;
|
|
nRunLengthTotal += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
nRunLength = 0;
|
|
bEOLReceived = TRUE;
|
|
goto D1DDone;
|
|
}
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// }else{
|
|
// nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
// goto Exit;
|
|
}
|
|
}
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
nRunLengthTotal += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
}while(nRunLength >= 64);
|
|
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
if (nRunLengthTotal < nWidth){
|
|
goto D1DW;
|
|
}
|
|
|
|
|
|
D1DDone:
|
|
// This was commented out for Wes at Microsoft who insists on writing bad data
|
|
// out to the file.
|
|
// Wes says that if the viewer sees invalid data, then it can either pad with zeros,
|
|
// or copy the previous line to the bad line, or leave the garbage data in tact.
|
|
// This decompression engine will leave the data in tact, resulting in the user
|
|
// either seeing the correct data, or garbage (which will hopefully let them know
|
|
// that there is a problem).
|
|
// I realize that this makes us no longer TIFF compliant (Version 6, page 44 paragraph 4),
|
|
// but there is nothing we can do about that within Wes's limitations.
|
|
//
|
|
// if (nRunLengthTotal != nWidth){
|
|
// nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
// goto Exit;
|
|
// }
|
|
if (nFlags & COMPRESS_BYTE_ALIGN_LINES){
|
|
nCodeWordLength = nCodeWordBits & 7;
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}
|
|
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
|
|
*puCodeWord = uCodeWord;
|
|
*pnCodeWordBits = nCodeWordBits;
|
|
*ppCompressedBuffer = pCompressedBuffer;
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: D2DLineToRunLengths
|
|
|
|
PURPOSE: This routine decompresses the image data using Group 4 2D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI D2DLineToRunLengths(PINT pnRunLengths, PINT pnOldRunLengths,
|
|
PBYTE *ppCompressedBuffer, PUINT puCodeWord,
|
|
PINT pnCodeWordBits, int nWidth, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
BOOL bEOLReceived;
|
|
int nLoop;
|
|
int nRunLengthIndex;
|
|
int nRunLength;
|
|
int nRunLengthTotal;
|
|
int nCodeWordLength;
|
|
int nCodeByte;
|
|
PBYTE pCompressedBuffer;
|
|
|
|
int nOldRunLength;
|
|
int nOldRunLenthIndex;
|
|
int nShift;
|
|
|
|
|
|
uCodeWord = *puCodeWord;
|
|
nCodeWordBits = *pnCodeWordBits;
|
|
nRunLength = 0;
|
|
nRunLengthTotal = 0;
|
|
nRunLengthIndex = 0;
|
|
bEOLReceived = FALSE;
|
|
pCompressedBuffer = *ppCompressedBuffer;
|
|
|
|
// Translate Codewords into Runlengths.
|
|
// Labels use Prefix = D2D (Decompress 2D), Suffix = W or B (White or Black).
|
|
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
|
|
if (!(uCodeWord >> (CODE_WORD_SHIFT - 3))){
|
|
// Must have an EOL.
|
|
if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
uCodeWord <<= 11;
|
|
nCodeWordBits -= 11;
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
for (nLoop = 0; nLoop < 16; nLoop++){
|
|
if (!(nShift = nFirstOneBit[uCodeWord >> CODE_WORD_SHIFT])){
|
|
break;
|
|
}
|
|
uCodeWord <<= nShift;
|
|
nCodeWordBits -= nShift;
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
}
|
|
if (!(uCodeWord & CODE_WORD_BIT_MASK)){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
uCodeWord <<= 1;
|
|
nCodeWordBits -= 1;
|
|
}
|
|
|
|
nOldRunLength = pnOldRunLengths[0];
|
|
nOldRunLenthIndex = 1;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
goto D2DDecodeCodeWord;
|
|
|
|
D2DNextCodeWord:
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
|
|
nRunLengthTotal += nRunLength;
|
|
if (nRunLengthTotal >= nWidth){
|
|
if (nRunLengthTotal > nWidth){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
goto D2DDone;
|
|
}
|
|
|
|
nOldRunLength -= nRunLength;
|
|
while(nOldRunLength <= 0){
|
|
nOldRunLength += pnOldRunLengths[nOldRunLenthIndex++];
|
|
}
|
|
|
|
|
|
D2DDecodeCodeWord:
|
|
switch (n2DCodeByteToState[uCodeWord >> CODE_WORD_SHIFT]){
|
|
case 0: // Pass.
|
|
uCodeWord <<= 4;
|
|
nCodeWordBits -= 4;
|
|
nRunLength = nOldRunLength + pnOldRunLengths[nOldRunLenthIndex];
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex + 1];
|
|
}
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 1: // Horizontal.
|
|
uCodeWord <<= 3;
|
|
nCodeWordBits -= 3;
|
|
if (!(nRunLengthIndex & 1)){
|
|
// White run length.
|
|
do{
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
nRunLength = nWCodeByte0ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte0ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
if (nRunLength == -1){
|
|
nRunLength = nWCodeByte1ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte1ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else if (nRunLength == -4){
|
|
nRunLength = nWCodeByte4ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte4ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
if (nRunLength < 0){
|
|
if (nRunLength == -7){
|
|
if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nWidth - nRunLengthTotal;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DEOL2;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
nRunLengthTotal += nRunLength;
|
|
nOldRunLength -= nRunLength;
|
|
while(nOldRunLength <= 0){
|
|
nOldRunLength += pnOldRunLengths[nOldRunLenthIndex++];
|
|
}
|
|
}while(nRunLength >= 64);
|
|
nRunLengthIndex++;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
|
|
// Black run length.
|
|
do{
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
nRunLength = nBCodeByte0ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte0ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
if (nRunLength == -4){
|
|
nRunLength = nBCodeByte4ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte4ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else if (nRunLength == -5){
|
|
nRunLength = nBCodeByte5ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte5ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
if (nRunLength < 0){
|
|
if (nRunLength == -7){
|
|
if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nWidth - nRunLengthTotal;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DEOL2;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
nRunLengthTotal += nRunLength;
|
|
nOldRunLength -= nRunLength;
|
|
while(nOldRunLength <= 0){
|
|
nOldRunLength += pnOldRunLengths[nOldRunLenthIndex++];
|
|
}
|
|
}while(nRunLength >= 64);
|
|
}else{
|
|
// Black run length.
|
|
do{
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
nRunLength = nBCodeByte0ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte0ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
if (nRunLength == -4){
|
|
nRunLength = nBCodeByte4ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte4ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else if (nRunLength == -5){
|
|
nRunLength = nBCodeByte5ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nBCodeByte5ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
if (nRunLength < 0){
|
|
if (nRunLength == -7){
|
|
if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nWidth - nRunLengthTotal;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DEOL2;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
nRunLengthTotal += nRunLength;
|
|
nOldRunLength -= nRunLength;
|
|
while(nOldRunLength <= 0){
|
|
nOldRunLength += pnOldRunLengths[nOldRunLenthIndex++];
|
|
}
|
|
}while(nRunLength >= 64);
|
|
nRunLengthIndex++;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
|
|
// White run length.
|
|
do{
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
nRunLength = nWCodeByte0ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte0ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
if (nRunLength < 0){
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
if (nRunLength == -1){
|
|
nRunLength = nWCodeByte1ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte1ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else if (nRunLength == -4){
|
|
nRunLength = nWCodeByte4ToRunLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
nCodeWordLength = nWCodeByte4ToCodeWordLength[uCodeWord >> CODE_WORD_SHIFT];
|
|
uCodeWord <<= nCodeWordLength;
|
|
nCodeWordBits -= nCodeWordLength;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
if (nRunLength < 0){
|
|
if (nRunLength == -7){
|
|
if (nFlags & COMPRESS_DONT_DELETE_EOLS){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nWidth - nRunLengthTotal;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DEOL2;
|
|
}else{
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
pnRunLengths[nRunLengthIndex] += nRunLength;
|
|
nRunLengthTotal += nRunLength;
|
|
nOldRunLength -= nRunLength;
|
|
while(nOldRunLength <= 0){
|
|
nOldRunLength += pnOldRunLengths[nOldRunLenthIndex++];
|
|
}
|
|
}while(nRunLength >= 64);
|
|
}
|
|
|
|
nRunLengthIndex++;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
nRunLength = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 2: // A1 = B1.
|
|
uCodeWord <<= 1;
|
|
nCodeWordBits -= 1;
|
|
nRunLength = nOldRunLength;
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex];
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 3: // A1 = B1 + 1.
|
|
uCodeWord <<= 3;
|
|
nCodeWordBits -= 3;
|
|
nRunLength = nOldRunLength + 1;
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex];
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 4: // A1 = B1 + 2.
|
|
uCodeWord <<= 6;
|
|
nCodeWordBits -= 6;
|
|
nRunLength = nOldRunLength + 2;
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex];
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 5: // A1 = B1 + 3.
|
|
uCodeWord <<= 7;
|
|
nCodeWordBits -= 7;
|
|
nRunLength = nOldRunLength + 3;
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex];
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 6: // A1 = B1 - 1.
|
|
uCodeWord <<= 3;
|
|
nCodeWordBits -= 3;
|
|
nRunLength = nOldRunLength - 1;
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex];
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 7: // A1 = B1 - 2.
|
|
uCodeWord <<= 6;
|
|
nCodeWordBits -= 6;
|
|
nRunLength = nOldRunLength - 2;
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex];
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 8: // A1 = B1 - 3.
|
|
uCodeWord <<= 7;
|
|
nCodeWordBits -= 7;
|
|
nRunLength = nOldRunLength - 3;
|
|
if ((nOldRunLenthIndex & 1) == (nRunLengthIndex & 1)){
|
|
nRunLength += pnOldRunLengths[nOldRunLenthIndex];
|
|
}
|
|
pnRunLengths[nRunLengthIndex++] += nRunLength;
|
|
pnRunLengths[nRunLengthIndex] = 0;
|
|
goto D2DNextCodeWord;
|
|
|
|
case 9: // EOL
|
|
uCodeWord <<= 8;
|
|
nCodeWordBits -= 8;
|
|
goto D2DEOL;
|
|
|
|
default: // Error.
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
D2DEOL:
|
|
// The first 8 bits of an EOL have been found.
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
|
|
nCodeByte = uCodeWord >> CODE_WORD_SHIFT;
|
|
if (!((uCodeWord >> (CODE_WORD_SHIFT + 5)))){
|
|
// Not enough zeros for an EOL.
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
uCodeWord <<= 3;
|
|
nCodeWordBits -= 3;
|
|
D2DEOL2:
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
|
|
for (nLoop = 0; nLoop < 16; nLoop++){
|
|
if (!(nShift = nFirstOneBit[uCodeWord >> CODE_WORD_SHIFT])){
|
|
break;
|
|
}
|
|
uCodeWord <<= nShift;
|
|
nCodeWordBits -= nShift;
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
}
|
|
if (!(uCodeWord & CODE_WORD_BIT_MASK)){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
uCodeWord <<= 1;
|
|
nCodeWordBits -= 1;
|
|
|
|
if (nRunLengthTotal != nWidth){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
bEOLReceived = TRUE;
|
|
goto D2DDone;
|
|
|
|
D2DDone:
|
|
pnRunLengths[nRunLengthIndex++] = 0;
|
|
|
|
if (!bEOLReceived && !(nFlags & COMPRESS_DONT_DELETE_EOLS)
|
|
&& !(uCodeWord >> (CODE_WORD_SHIFT - 3))){
|
|
// Must have an EOL.
|
|
uCodeWord <<= 11;
|
|
nCodeWordBits -= 11;
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
for (nLoop = 0; nLoop < 16; nLoop++){
|
|
if (!(nShift = nFirstOneBit[uCodeWord >> CODE_WORD_SHIFT])){
|
|
break;
|
|
}
|
|
uCodeWord <<= nShift;
|
|
nCodeWordBits -= nShift;
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
}
|
|
if (!(uCodeWord & CODE_WORD_BIT_MASK)){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
uCodeWord <<= 1;
|
|
nCodeWordBits -= 1;
|
|
}
|
|
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
pnRunLengths[++nRunLengthIndex] = 0;
|
|
|
|
*puCodeWord = uCodeWord;
|
|
*pnCodeWordBits = nCodeWordBits;
|
|
*ppCompressedBuffer = pCompressedBuffer;
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: RunLengthsToLine
|
|
|
|
PURPOSE: This routine calculates the line of image data from run lengths.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI RunLengthsToLine(PBYTE pImageData, PINT pnRunLengths,
|
|
int nWidthPixels, int nWidthBytes, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
int nRunLengthIndex;
|
|
int nRunLength;
|
|
int nRLTotal;
|
|
PBYTE pImageData2;
|
|
int nBit;
|
|
|
|
|
|
nRLTotal = 0;
|
|
nRunLengthIndex = 0;
|
|
|
|
if (nFlags & COMPRESS_NEGATE_BITS){
|
|
// White = 0, Black = 1.
|
|
if (nFlags & COMPRESS_EXPANDED_IS_LTR){
|
|
// Don't reverse the bits.
|
|
while(nRLTotal < nWidthPixels){
|
|
// Ignor white runlengths.
|
|
nRLTotal += pnRunLengths[nRunLengthIndex++];
|
|
|
|
// Set black pixels.
|
|
nRunLength = pnRunLengths[nRunLengthIndex++];
|
|
pImageData2 = pImageData + (nRLTotal >> 3);
|
|
|
|
// Do first byte.
|
|
nBit = nRLTotal & 7;
|
|
nRLTotal += nRunLength;
|
|
if (nRunLength <= (8 - nBit)){
|
|
*pImageData2 ^= nRunLengthTo1Bits[nRunLength] >> nBit;
|
|
continue;
|
|
}else{
|
|
*(pImageData2++) ^= 0x0ff >> nBit;
|
|
nRunLength -= 8 - nBit;
|
|
}
|
|
|
|
// Do middle bytes.
|
|
while(nRunLength >= 8){
|
|
*(pImageData2++) = 0x0ff;
|
|
nRunLength -= 8;
|
|
}
|
|
|
|
// Do last byte.
|
|
*pImageData2 = nRunLengthTo1Bits[nRunLength];
|
|
}
|
|
}else{
|
|
// Reverse the bits.
|
|
while(nRLTotal < nWidthPixels){
|
|
// Ignor white runlengths.
|
|
nRLTotal += pnRunLengths[nRunLengthIndex++];
|
|
|
|
// Set black pixels.
|
|
nRunLength = pnRunLengths[nRunLengthIndex++];
|
|
pImageData2 = pImageData + (nRLTotal >> 3);
|
|
|
|
// Do first byte.
|
|
nBit = nRLTotal & 7;
|
|
nRLTotal += nRunLength;
|
|
if (nRunLength <= (8 - nBit)){
|
|
*pImageData2 ^= (nRunLengthTo1BitsR[nRunLength] << nBit) & 0x0ff;
|
|
continue;
|
|
}else{
|
|
*(pImageData2++) ^= 0x0ff >> nBit;
|
|
nRunLength -= 8 - nBit;
|
|
}
|
|
|
|
// Do middle bytes.
|
|
while(nRunLength >= 8){
|
|
*(pImageData2++) = 0x0ff;
|
|
nRunLength -= 8;
|
|
}
|
|
|
|
// Do last byte.
|
|
*pImageData2 = nRunLengthTo1BitsR[nRunLength];
|
|
}
|
|
}
|
|
}else{
|
|
// White = 1, Black = 0.
|
|
if (nFlags & COMPRESS_EXPANDED_IS_LTR){
|
|
// Don't reverse the bits.
|
|
while(nRLTotal < nWidthPixels){
|
|
// Ignor white runlengths.
|
|
nRLTotal += pnRunLengths[nRunLengthIndex++];
|
|
|
|
// Set black pixels.
|
|
nRunLength = pnRunLengths[nRunLengthIndex++];
|
|
pImageData2 = pImageData + (nRLTotal >> 3);
|
|
|
|
// Do first byte.
|
|
nBit = nRLTotal & 7;
|
|
nRLTotal += nRunLength;
|
|
if (nRunLength <= (8 - nBit)){
|
|
*pImageData2 ^= nRunLengthTo1Bits[nRunLength] >> nBit;
|
|
continue;
|
|
}else{
|
|
*(pImageData2++) ^= 0x0ff >> nBit;
|
|
nRunLength -= 8 - nBit;
|
|
}
|
|
|
|
// Do middle bytes.
|
|
while(nRunLength >= 8){
|
|
*(pImageData2++) = 0;
|
|
nRunLength -= 8;
|
|
}
|
|
|
|
// Do last byte.
|
|
*pImageData2 = nRunLengthTo0Bits[nRunLength];
|
|
}
|
|
}else{
|
|
// Reverse the bits.
|
|
while(nRLTotal < nWidthPixels){
|
|
// Ignor white runlengths.
|
|
nRLTotal += pnRunLengths[nRunLengthIndex++];
|
|
|
|
// Set black pixels.
|
|
nRunLength = pnRunLengths[nRunLengthIndex++];
|
|
pImageData2 = pImageData + (nRLTotal >> 3);
|
|
|
|
// Do first byte.
|
|
nBit = nRLTotal & 7;
|
|
nRLTotal += nRunLength;
|
|
if (nRunLength <= (8 - nBit)){
|
|
*pImageData2 ^= (nRunLengthTo1BitsR[nRunLength] << nBit) & 0x0ff;
|
|
continue;
|
|
}else{
|
|
*(pImageData2++) ^= 0x0ff >> nBit;
|
|
nRunLength -= 8 - nBit;
|
|
}
|
|
|
|
// Do middle bytes.
|
|
while(nRunLength >= 8){
|
|
*(pImageData2++) = 0;
|
|
nRunLength -= 8;
|
|
}
|
|
|
|
// Do last byte.
|
|
*pImageData2 = nRunLengthTo0BitsR[nRunLength];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: Decompress0D
|
|
|
|
PURPOSE: This routine decompresses the image data using nncompressed data.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI Decompress0D(int nWidth, int nHeight, int nWidthBytes, PBYTE pImageData,
|
|
PBYTE pCompressedBuffer, int nCompressedBufferSize, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
|
|
if ((!(nFlags & COMPRESS_COMPRESSED_IS_LTR) && (nFlags & COMPRESS_EXPANDED_IS_LTR))
|
|
|| ((nFlags & COMPRESS_COMPRESSED_IS_LTR) && !(nFlags & COMPRESS_EXPANDED_IS_LTR))){
|
|
CheckError2( ReverseBits(pCompressedBuffer, nCompressedBufferSize))
|
|
}
|
|
|
|
memcpy(pImageData, pCompressedBuffer, nCompressedBufferSize);
|
|
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
CheckError2( NegateBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: DecompressG31D
|
|
|
|
PURPOSE: This routine decompresses the image data using Group 3 1D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI DecompressG31D(int nWidth, int nHeight, int nWidthBytes, PBYTE pImageData,
|
|
PBYTE pCompressedBuffer, int nCompressedBufferSize, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nLine;
|
|
int nRunLengths[20000];
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
PBYTE pCompressedBufferEnd;
|
|
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBuffer, nCompressedBufferSize))
|
|
}
|
|
|
|
|
|
if (nFlags & COMPRESS_NEGATE_BITS){
|
|
memset(pImageData, 0x00, nHeight * nWidthBytes);
|
|
}else{
|
|
memset(pImageData, 0xff, nHeight * nWidthBytes);
|
|
}
|
|
|
|
pCompressedBufferEnd = pCompressedBuffer + nCompressedBufferSize;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x01;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x01;
|
|
|
|
uCodeWord = 0;
|
|
nCodeWordBits = 0;
|
|
|
|
for (nLine = 0; nLine < nHeight; nLine++){
|
|
if (pCompressedBuffer >= pCompressedBufferEnd){
|
|
nRunLengths[0] = nWidth;
|
|
nRunLengths[1] = 0;
|
|
}else{
|
|
CheckError2( D1DLineToRunLengths(&nRunLengths[0], &pCompressedBuffer,
|
|
&uCodeWord, &nCodeWordBits, nWidth, nFlags))
|
|
}
|
|
if (nRunLengths[1]){
|
|
CheckError2( RunLengthsToLine(pImageData + (nLine * nWidthBytes),
|
|
&nRunLengths[0], nWidth, nWidthBytes, nFlags))
|
|
}
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: DecompressG32D
|
|
|
|
PURPOSE: This routine decompresses the image data using Group 3 2D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI DecompressG32D(int nWidth, int nHeight, int nWidthBytes, PBYTE pImageData,
|
|
PBYTE pCompressedBuffer, int nCompressedBufferSize, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nLine;
|
|
int nRunLengths1[20000];
|
|
int nRunLengths2[20000];
|
|
PINT pnRunLengths;
|
|
PINT pnOldRunLengths;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
PBYTE pCompressedBufferEnd;
|
|
BOOL b1D;
|
|
int nLoop;
|
|
int nShift;
|
|
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBuffer, nCompressedBufferSize))
|
|
}
|
|
|
|
|
|
if (nFlags & COMPRESS_NEGATE_BITS){
|
|
memset(pImageData, 0x00, nHeight * nWidthBytes);
|
|
}else{
|
|
memset(pImageData, 0xff, nHeight * nWidthBytes);
|
|
}
|
|
|
|
pCompressedBufferEnd = pCompressedBuffer + nCompressedBufferSize;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x01;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x01;
|
|
|
|
uCodeWord = 0;
|
|
nCodeWordBits = 0;
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
nFlags |= COMPRESS_DONT_DELETE_EOLS;
|
|
b1D = TRUE;
|
|
|
|
for (nLine = 0; nLine < nHeight; nLine++){
|
|
if (nLine & 1){
|
|
pnRunLengths = &nRunLengths1[0];
|
|
pnOldRunLengths = &nRunLengths2[0];
|
|
}else{
|
|
pnRunLengths = &nRunLengths2[0];
|
|
pnOldRunLengths = &nRunLengths1[0];
|
|
}
|
|
if (!(uCodeWord >> (CODE_WORD_SHIFT - 3))){
|
|
// Must have an EOL.
|
|
uCodeWord <<= 11;
|
|
nCodeWordBits -= 11;
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
for (nLoop = 0; nLoop < 16; nLoop++){
|
|
if (!(nShift = nFirstOneBit[uCodeWord >> CODE_WORD_SHIFT])){
|
|
break;
|
|
}
|
|
uCodeWord <<= nShift;
|
|
nCodeWordBits -= nShift;
|
|
if (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
}
|
|
if (!(uCodeWord & CODE_WORD_BIT_MASK)){
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
uCodeWord <<= 1;
|
|
nCodeWordBits -= 1;
|
|
if (!(uCodeWord & CODE_WORD_BIT_MASK)){
|
|
b1D = FALSE;
|
|
}else{
|
|
b1D = TRUE;
|
|
}
|
|
uCodeWord <<= 1;
|
|
nCodeWordBits -= 1;
|
|
}
|
|
|
|
if (pCompressedBuffer >= pCompressedBufferEnd){
|
|
pnRunLengths[0] = nWidth;
|
|
pnRunLengths[1] = 0;
|
|
}else{
|
|
if (b1D){
|
|
CheckError2( D1DLineToRunLengths(pnRunLengths, &pCompressedBuffer,
|
|
&uCodeWord, &nCodeWordBits, nWidth, nFlags))
|
|
}else{
|
|
CheckError2( D2DLineToRunLengths(pnRunLengths, pnOldRunLengths,
|
|
&pCompressedBuffer, &uCodeWord, &nCodeWordBits, nWidth, nFlags))
|
|
}
|
|
}
|
|
if (pnRunLengths[1]){
|
|
CheckError2( RunLengthsToLine(pImageData + (nLine * nWidthBytes),
|
|
pnRunLengths, nWidth, nWidthBytes, nFlags))
|
|
}
|
|
}
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: DecompressG42D
|
|
|
|
PURPOSE: This routine decompresses the image data using Group 4 2D.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI DecompressG42D(int nWidth, int nHeight, int nWidthBytes, PBYTE pImageData,
|
|
PBYTE pCompressedBuffer, int nCompressedBufferSize, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
int nLine;
|
|
int nRunLengths1[20000];
|
|
int nRunLengths2[20000];
|
|
PINT pnRunLengths;
|
|
PINT pnOldRunLengths;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
PBYTE pCompressedBufferEnd;
|
|
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBuffer, nCompressedBufferSize))
|
|
}
|
|
|
|
if (nFlags & COMPRESS_NEGATE_BITS){
|
|
memset(pImageData, 0x00, nHeight * nWidthBytes);
|
|
}else{
|
|
memset(pImageData, 0xff, nHeight * nWidthBytes);
|
|
}
|
|
|
|
pCompressedBufferEnd = pCompressedBuffer + nCompressedBufferSize;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x01;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x01;
|
|
|
|
// Init to all white line.
|
|
nRunLengths1[0] = nWidth;
|
|
nRunLengths1[1] = 0;
|
|
nRunLengths1[2] = 0;
|
|
nRunLengths1[3] = 0;
|
|
nRunLengths1[4] = 0;
|
|
nRunLengths1[5] = 0;
|
|
|
|
uCodeWord = 0;
|
|
nCodeWordBits = 0;
|
|
while (nCodeWordBits <= CODE_WORD_SHIFT){
|
|
uCodeWord |= *(pCompressedBuffer++) << (CODE_WORD_SHIFT - nCodeWordBits);
|
|
nCodeWordBits += 8;
|
|
}
|
|
|
|
for (nLine = 0; nLine < nHeight; nLine++){
|
|
if (nLine & 1){
|
|
pnRunLengths = &nRunLengths1[0];
|
|
pnOldRunLengths = &nRunLengths2[0];
|
|
}else{
|
|
pnRunLengths = &nRunLengths2[0];
|
|
pnOldRunLengths = &nRunLengths1[0];
|
|
}
|
|
if (!(uCodeWord >> (CODE_WORD_SHIFT - 3))){ // EOFB. Fill image with white lines.
|
|
pnRunLengths[0] = nWidth;
|
|
pnRunLengths[1] = 0;
|
|
pnRunLengths[2] = 0;
|
|
pnRunLengths[3] = 0;
|
|
pnRunLengths[4] = 0;
|
|
pnRunLengths[5] = 0;
|
|
}else{
|
|
CheckError2( D2DLineToRunLengths(pnRunLengths, pnOldRunLengths,
|
|
&pCompressedBuffer, &uCodeWord, &nCodeWordBits, nWidth, nFlags))
|
|
}
|
|
if (pnRunLengths[1]){
|
|
CheckError2( RunLengthsToLine(pImageData + (nLine * nWidthBytes),
|
|
pnRunLengths, nWidth, nWidthBytes, nFlags))
|
|
}
|
|
}
|
|
|
|
// Don't look for EOFB. Some images such as the Teranet images include
|
|
// extra lines of image data.
|
|
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: CompressLZW
|
|
|
|
PURPOSE: This routine compresses the image data using LZW.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI CompressLZW(int nWidth, int nHeight, int nWidthBytes, PBYTE pImageData,
|
|
int nImageType, PBYTE *ppCompressedBuffer, PINT pnCompressedBufferSize,
|
|
int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
typedef struct tagLZWCodeTable{
|
|
int nBytePlusCode; // Byte = bits 23-16, Code = bits 11-0
|
|
int nNextCode;
|
|
} LZWCODETABLE;
|
|
|
|
LZWCODETABLE LZWCodeTable[4100];
|
|
int nCode;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
PBYTE pCompressedBufferStart;
|
|
PBYTE pCompressedBuffer;
|
|
int nCompressedBufferMaxSize;
|
|
int nTotalBytes;
|
|
int nCodeSize;
|
|
int nLastCodeIndex;
|
|
int nIndex;
|
|
int nLoop;
|
|
BOOL bReverseImage = FALSE;
|
|
BOOL bNegateImage = FALSE;
|
|
BOOL bHorzPredictImage = FALSE;
|
|
PBYTE pImageData2;
|
|
|
|
int nLine;
|
|
int nPixel1;
|
|
int nPixel2;
|
|
int nPixel3;
|
|
int nPrevPixel1;
|
|
int nPrevPixel2;
|
|
int nPrevPixel3;
|
|
|
|
|
|
if (nFlags & COMPRESS_HORZ_PREDICTOR){
|
|
bHorzPredictImage = TRUE;
|
|
pImageData2 = pImageData;
|
|
switch (nImageType){
|
|
case ITYPE_GRAY4:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPrevPixel1 = 0;
|
|
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
|
nPixel1 = nPrevPixel1 - ((*pImageData2 >> 4) & 0x0f);
|
|
nPrevPixel1 = ((*pImageData2 >> 4) & 0x0f);
|
|
nPixel2 = nPrevPixel1 - (*pImageData2 & 0x0f);
|
|
nPrevPixel1 = (*pImageData2 & 0x0f);
|
|
*(pImageData2++) = (nPixel1 << 4) | (nPixel2 & 0x0f);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_GRAY8:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPrevPixel1 = 0;
|
|
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
|
nPixel1 = nPrevPixel1 - *pImageData2;
|
|
nPrevPixel1 = *pImageData2;
|
|
*(pImageData2++) = nPixel1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_RGB24:
|
|
case ITYPE_BGR24:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPrevPixel1 = 0;
|
|
nPrevPixel2 = 0;
|
|
nPrevPixel3 = 0;
|
|
for (nLoop = nWidth; nLoop; nLoop--){
|
|
nPixel1 = nPrevPixel1 - *pImageData2;
|
|
nPrevPixel1 = *pImageData2;
|
|
*(pImageData2++) = nPixel1;
|
|
|
|
nPixel2 = nPrevPixel2 - *pImageData2;
|
|
nPrevPixel2 = *pImageData2;
|
|
*(pImageData2++) = nPixel2;
|
|
|
|
nPixel3 = nPrevPixel3 - *pImageData2;
|
|
nPrevPixel3 = *pImageData2;
|
|
*(pImageData2++) = nPixel3;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_BI_LEVEL:
|
|
case ITYPE_PAL4:
|
|
case ITYPE_CUSPAL8:
|
|
case ITYPE_COMPAL8:
|
|
default:
|
|
// We can not do horizontal prediction on non-linear data.
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// pImageData++;
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
bNegateImage = TRUE;
|
|
CheckError2( NegateBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
if (!(nFlags & COMPRESS_EXPANDED_IS_LTR)){
|
|
bReverseImage = TRUE;
|
|
CheckError2( ReverseBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
|
|
pImageData2 = pImageData;
|
|
uCodeWord = 0;
|
|
nCodeWordBits = 0;
|
|
|
|
nCompressedBufferMaxSize = max(10, (nHeight * nWidthBytes) << 2);
|
|
if (!(pCompressedBufferStart = VirtualAlloc(NULL, nCompressedBufferMaxSize,
|
|
MEM_COMMIT, PAGE_READWRITE))){
|
|
nStatus = Error(DISPLAY_CANTALLOC);
|
|
goto Exit;
|
|
}
|
|
pCompressedBuffer = pCompressedBufferStart;
|
|
|
|
memset(LZWCodeTable, 0, sizeof(LZWCODETABLE) * 4100);
|
|
for (nLoop = 0; nLoop < 256; nLoop++){
|
|
LZWCodeTable[nLoop].nBytePlusCode = nLoop;
|
|
}
|
|
nLastCodeIndex = 258;
|
|
nCodeSize = 9;
|
|
nCode = *(pImageData2++);
|
|
|
|
for (nTotalBytes = (nHeight * nWidthBytes) - 1; nTotalBytes; nTotalBytes--){
|
|
nCode |= *(pImageData2++) << 16;
|
|
if ((nIndex = LZWCodeTable[nCode & 0x0ffff].nNextCode)){
|
|
for (; nIndex < nLastCodeIndex; nIndex++){
|
|
if (LZWCodeTable[nIndex].nBytePlusCode == nCode){
|
|
break;
|
|
}
|
|
}
|
|
if (nIndex < nLastCodeIndex){
|
|
// Code found.
|
|
nCode = nIndex;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Code not found in table.
|
|
uCodeWord = (uCodeWord << nCodeSize) | (nCode & 0x0ffff);
|
|
nCodeWordBits += nCodeSize - 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
if (nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
if (!LZWCodeTable[nCode & 0x0ffff].nNextCode){
|
|
LZWCodeTable[nCode & 0x0ffff].nNextCode = nLastCodeIndex;
|
|
}
|
|
LZWCodeTable[nLastCodeIndex++].nBytePlusCode = nCode;
|
|
nCode >>= 16;
|
|
if (nLastCodeIndex > 511){
|
|
if (nLastCodeIndex > 1023){
|
|
if (nLastCodeIndex > 2047){
|
|
if (nLastCodeIndex > 4093){
|
|
if (nTotalBytes > 1){
|
|
// Write out last code.
|
|
uCodeWord = (uCodeWord << 12) | nCode;
|
|
nCodeWordBits += 4;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
|
|
// Write out clear code.
|
|
uCodeWord = (uCodeWord << 12) | 256;
|
|
nCodeWordBits += 4;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
if (nCodeWordBits >= 8){
|
|
nCodeWordBits -= 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}
|
|
|
|
// Reset table.
|
|
memset(&LZWCodeTable[258], 0, sizeof(LZWCODETABLE) * 3842);
|
|
nLastCodeIndex = 258;
|
|
nCodeSize = 9;
|
|
}
|
|
continue;
|
|
}else{
|
|
nCodeSize = 12;
|
|
continue;
|
|
}
|
|
}else{
|
|
nCodeSize = 11;
|
|
continue;
|
|
}
|
|
}else{
|
|
nCodeSize = 10;
|
|
continue;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// Write out last code.
|
|
uCodeWord = (uCodeWord << nCodeSize) | nCode;
|
|
nCodeWordBits += nCodeSize - 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
if (nLastCodeIndex > 509){
|
|
if (nLastCodeIndex > 1021){
|
|
if (nLastCodeIndex > 2045){
|
|
nCodeSize = 12;
|
|
}else{
|
|
nCodeSize = 11;
|
|
}
|
|
}else{
|
|
nCodeSize = 10;
|
|
}
|
|
}
|
|
|
|
// Write out clear code.
|
|
uCodeWord = (uCodeWord << nCodeSize) | 256;
|
|
nCodeWordBits += nCodeSize - 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
if (nLastCodeIndex > 509){
|
|
if (nLastCodeIndex > 1021){
|
|
if (nLastCodeIndex > 2045){
|
|
nCodeSize = 12;
|
|
}else{
|
|
nCodeSize = 11;
|
|
}
|
|
}else{
|
|
nCodeSize = 10;
|
|
}
|
|
}
|
|
|
|
// Write out end of information code.
|
|
uCodeWord = (uCodeWord << nCodeSize) | 257;
|
|
nCodeWordBits += nCodeSize - 8;
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
|
|
// Write last piece of data out.
|
|
while(nCodeWordBits > 0){
|
|
nCodeWordBits -= 8;
|
|
if (nCodeWordBits >= 0){
|
|
*(pCompressedBuffer++) = uCodeWord >> nCodeWordBits;
|
|
}else{
|
|
*(pCompressedBuffer++) = uCodeWord << -nCodeWordBits;
|
|
}
|
|
}
|
|
|
|
nCompressedBufferMaxSize = (pCompressedBuffer - pCompressedBufferStart) + 4;
|
|
// if (nStatus = ReAllocateMemory(nCompressedBufferMaxSize, &pCompressedBufferStart, NO_INIT)){
|
|
// goto Exit;
|
|
// }
|
|
*ppCompressedBuffer = pCompressedBufferStart;
|
|
*pnCompressedBufferSize = nCompressedBufferMaxSize - 4;
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBufferStart, nCompressedBufferMaxSize - 4))
|
|
}
|
|
|
|
|
|
Exit:
|
|
if (bReverseImage){
|
|
ReverseBits(pImageData, nWidthBytes * nHeight);
|
|
}
|
|
if (bNegateImage){
|
|
NegateBits(pImageData, nWidthBytes * nHeight);
|
|
}
|
|
if (bHorzPredictImage){
|
|
pImageData2 = pImageData;
|
|
switch (nImageType){
|
|
case ITYPE_GRAY4:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPixel2 = 0;
|
|
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
|
nPixel1 = (nPixel2 + ((*pImageData2 >> 4) & 0x0f)) & 0x0f;
|
|
nPixel2 = (nPixel1 + (*pImageData2 & 0x0f)) & 0x0f;
|
|
*(pImageData2++) = (nPixel1 << 4) | (nPixel2 & 0x0f);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_GRAY8:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPixel1 = 0;
|
|
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
|
nPixel1 = (nPixel1 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_RGB24:
|
|
case ITYPE_BGR24:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPixel1 = 0;
|
|
nPixel2 = 0;
|
|
nPixel3 = 0;
|
|
for (nLoop = nWidth; nLoop; nLoop--){
|
|
nPixel1 = (nPixel1 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel1;
|
|
|
|
nPixel2 = (nPixel2 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel2;
|
|
|
|
nPixel3 = (nPixel3 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel3;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_BI_LEVEL:
|
|
case ITYPE_PAL4:
|
|
case ITYPE_CUSPAL8:
|
|
case ITYPE_COMPAL8:
|
|
default:
|
|
// We can not do horizontal prediction on non-linear data.
|
|
break;
|
|
}
|
|
}
|
|
return(nStatus);
|
|
}
|
|
/****************************************************************************
|
|
|
|
FUNCTION: DecompressLZW
|
|
|
|
PURPOSE: This routine decompresses the image data using LZW.
|
|
|
|
****************************************************************************/
|
|
|
|
int WINAPI DecompressLZW(int nWidth, int nHeight, int nWidthBytes, PBYTE pImageData,
|
|
int nImageType, PBYTE pCompressedBuffer, int nCompressedBufferSize, int nFlags){
|
|
|
|
int nStatus = 0;
|
|
|
|
typedef struct tagLZWDecodeTable{
|
|
int nByte;
|
|
int nNextCode;
|
|
} LZWDECODETABLE;
|
|
|
|
LZWDECODETABLE LZWDecodeTable[4100];
|
|
int nCode;
|
|
int nOrginalCode;
|
|
UINT uCodeWord;
|
|
int nCodeWordBits;
|
|
int nTotalBytes;
|
|
int nCodeSize;
|
|
int nLastCodeIndex;
|
|
int nStringIndex;
|
|
int nLoop;
|
|
uchar cString[4100];
|
|
PBYTE pImageData2;
|
|
PBYTE pCompressedBufferEnd;
|
|
|
|
int nLine;
|
|
int nPixel1;
|
|
int nPixel2;
|
|
int nPixel3;
|
|
|
|
|
|
if (!(nFlags & COMPRESS_COMPRESSED_IS_LTR)){
|
|
CheckError2( ReverseBits(pCompressedBuffer, nCompressedBufferSize))
|
|
}
|
|
|
|
pCompressedBufferEnd = pCompressedBuffer + nCompressedBufferSize;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x00;
|
|
*(pCompressedBufferEnd++) = 0x01;
|
|
|
|
pImageData2 = pImageData;
|
|
for (nLoop = 0; nLoop < 256; nLoop++){
|
|
LZWDecodeTable[nLoop].nByte = nLoop;
|
|
}
|
|
nLastCodeIndex = 257;
|
|
nCodeSize = 9;
|
|
|
|
uCodeWord = *(pCompressedBuffer++) << 24;
|
|
uCodeWord |= *(pCompressedBuffer++) << 16;
|
|
uCodeWord |= *(pCompressedBuffer++) << 8;
|
|
uCodeWord |= *(pCompressedBuffer++);
|
|
nCodeWordBits = 32;
|
|
|
|
nTotalBytes = (nHeight * nWidthBytes) - 1;
|
|
while(nTotalBytes > 0){
|
|
nCode = uCodeWord >> (32 - nCodeSize);
|
|
nOrginalCode = nCode;
|
|
nCodeWordBits -= nCodeSize - 8;
|
|
uCodeWord = (uCodeWord << nCodeSize) | (*(pCompressedBuffer++) << (32 - nCodeWordBits));
|
|
if (pCompressedBuffer >= pCompressedBufferEnd){
|
|
// We have read too much data. Abort.
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
if (nCodeWordBits <= 24){
|
|
nCodeWordBits += 8;
|
|
uCodeWord |= *(pCompressedBuffer++) << (32 - nCodeWordBits);
|
|
}
|
|
|
|
if (nCode < 258){
|
|
if (nCode > 255){
|
|
// Clear code or end of information code.
|
|
if (nCode = 256){
|
|
// Clear code.
|
|
nLastCodeIndex = 257;
|
|
nCodeSize = 9;
|
|
continue;
|
|
}
|
|
// End of information.
|
|
// Since we are still in this loop we haven't gotten all of
|
|
// our information yet. Therefore this is an error.
|
|
nStatus = Error(DISPLAY_COMPRESS_BAD_DATA);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
// Normal code.
|
|
LZWDecodeTable[nLastCodeIndex + 1].nNextCode = nCode;
|
|
nStringIndex = 0;
|
|
while(1){
|
|
cString[nStringIndex++] = LZWDecodeTable[nCode].nByte;
|
|
if (nCode < 256){
|
|
break;
|
|
}
|
|
nCode = LZWDecodeTable[nCode].nNextCode;
|
|
}
|
|
nTotalBytes -= nStringIndex;
|
|
LZWDecodeTable[nLastCodeIndex++].nByte = cString[nStringIndex - 1];
|
|
cString[0] = LZWDecodeTable[nOrginalCode].nByte; // Just in case we just changed it.
|
|
|
|
// Reverse the string into the image data.
|
|
while(nStringIndex){
|
|
*(pImageData2++) = cString[--nStringIndex];
|
|
}
|
|
if (nLastCodeIndex > 510){
|
|
if (nLastCodeIndex > 1022){
|
|
if (nLastCodeIndex > 2046){
|
|
nCodeSize = 12;
|
|
}else{
|
|
nCodeSize = 11;
|
|
}
|
|
}else{
|
|
nCodeSize = 10;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((nFlags & COMPRESS_NEGATE_BITS)){
|
|
CheckError2( NegateBits(pImageData, nWidthBytes * nHeight))
|
|
}
|
|
// if (!(nFlags & COMPRESS_EXPANDED_IS_LTR)){
|
|
// if (nStatus = ReverseBits(pImageData, nWidthBytes * nHeight)){
|
|
// goto Exit;
|
|
// }
|
|
// }
|
|
|
|
if (nFlags & COMPRESS_HORZ_PREDICTOR){
|
|
pImageData2 = pImageData;
|
|
switch (nImageType){
|
|
case ITYPE_GRAY4:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPixel2 = 0;
|
|
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
|
nPixel1 = (nPixel2 + ((*pImageData2 >> 4) & 0x0f)) & 0x0f;
|
|
nPixel2 = (nPixel1 + (*pImageData2 & 0x0f)) & 0x0f;
|
|
*(pImageData2++) = (nPixel1 << 4) | (nPixel2 & 0x0f);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_GRAY8:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPixel1 = 0;
|
|
for (nLoop = nWidthBytes; nLoop; nLoop--){
|
|
nPixel1 = (nPixel1 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel1;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_RGB24:
|
|
case ITYPE_BGR24:
|
|
for (nLine = nHeight; nLine; nLine--){
|
|
nPixel1 = 0;
|
|
nPixel2 = 0;
|
|
nPixel3 = 0;
|
|
for (nLoop = nWidth; nLoop; nLoop--){
|
|
nPixel1 = (nPixel1 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel1;
|
|
|
|
nPixel2 = (nPixel2 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel2;
|
|
|
|
nPixel3 = (nPixel3 + *pImageData2) & 0x0ff;
|
|
*(pImageData2++) = nPixel3;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case ITYPE_BI_LEVEL:
|
|
case ITYPE_PAL4:
|
|
case ITYPE_CUSPAL8:
|
|
case ITYPE_COMPAL8:
|
|
default:
|
|
// We can not do horizontal prediction on non-linear data.
|
|
break;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
return(nStatus);
|
|
}
|