1/*
2 * Compress3.cpp
3 * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
4 */
5
6
7// #define DBG_CON_STREAM
8
9#ifdef DBG_CON_STREAM
10#include <fstream>
11using namespace std;
12#endif
13
14#include "Compress3.h"
15
16#define PACK_TYPE	2
17
18
19int
20compress3(unsigned char* pOut, unsigned char* pIn, int n)
21{
22	int count;
23	int count_byte;
24	unsigned char* pBase;
25	unsigned char* pLast;
26	unsigned char keep;
27
28	count = 0;
29	count_byte = 0;
30
31	keep   = ~(*pIn);
32	pLast  = pIn + n;
33
34	for (pBase = pIn; (pBase < pLast) && (count_byte < n) ; pBase++) {
35		if (*pBase == keep) {
36			if (count < 0xff + PACK_TYPE) {
37				count++;
38			} else {
39				*pOut++ = keep;
40				*pOut++ = count - PACK_TYPE;
41				count = 1;
42				keep  = *pOut++ = *pBase;
43				count_byte += 3;
44			}
45		} else {
46			if (count > 1) {
47				*pOut++ = keep;
48				*pOut++ = count - PACK_TYPE;
49				count_byte += 2;
50			}
51			count = 1;
52			keep  = *pOut++ = *pBase;
53			count_byte++;
54		}
55	}
56
57	if (count > 1) {
58		if ((count_byte + 2) < n) {
59			*pOut++ = keep;
60			*pOut++ = count - PACK_TYPE;
61			count_byte += 2;
62		} else
63			count_byte = n;
64	}
65
66	return count_byte;
67}
68
69
70#ifdef DBG_CON_STREAM
71
72int
73main(int argc, char **argv)
74{
75	if (argc < 2)
76		return -1;
77
78	ifstream ifs(*++argv, ios::binary | ios::nocreate);
79	if (!ifs)
80		return -1;
81
82	ifs.seekg(0, ios::end);
83	long size = ifs.tellg();
84	ifs.seekg(0, ios::beg);
85
86	unsigned char* pIn  = new unsigned char[size];
87	unsigned char* pOut = new unsigned char[size * 3];
88
89	ifs.read(pIn, size);
90
91	int cnt = PackBits(pOut, pIn, size);
92
93	ofstream ofs("test.bin", ios::binary);
94	ofs.write(pOut, cnt);
95
96	delete [] pIn;
97	delete [] pOut;
98
99}
100
101#endif
102