xref: /haiku/src/libs/print/libprint/PackBits.cpp (revision 12fd6cc2e713920c32d691c50b881517a0c53988)
1*12fd6cc2SKarsten Heimrich /*
2*12fd6cc2SKarsten Heimrich  * PackBits.cpp
3*12fd6cc2SKarsten Heimrich  * Copyright 1999-2000 Y.Takagi. All Rights Reserved.
4*12fd6cc2SKarsten Heimrich  */
5*12fd6cc2SKarsten Heimrich 
6*12fd6cc2SKarsten Heimrich //#define DBG_CON_STREAM
7*12fd6cc2SKarsten Heimrich 
8*12fd6cc2SKarsten Heimrich #ifdef DBG_CON_STREAM
9*12fd6cc2SKarsten Heimrich #include <fstream>
10*12fd6cc2SKarsten Heimrich #endif
11*12fd6cc2SKarsten Heimrich 
12*12fd6cc2SKarsten Heimrich #include <stdio.h>
13*12fd6cc2SKarsten Heimrich #include <string.h>
14*12fd6cc2SKarsten Heimrich #include "PackBits.h"
15*12fd6cc2SKarsten Heimrich 
16*12fd6cc2SKarsten Heimrich #if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE))
17*12fd6cc2SKarsten Heimrich using namespace std;
18*12fd6cc2SKarsten Heimrich #else
19*12fd6cc2SKarsten Heimrich #define std
20*12fd6cc2SKarsten Heimrich #endif
21*12fd6cc2SKarsten Heimrich 
22*12fd6cc2SKarsten Heimrich #define	MAXINBYTES		127
23*12fd6cc2SKarsten Heimrich #define CONTROL1(i)		-i
24*12fd6cc2SKarsten Heimrich #define CONTROL2(i)		i
25*12fd6cc2SKarsten Heimrich 
26*12fd6cc2SKarsten Heimrich enum STATUS {
27*12fd6cc2SKarsten Heimrich 	INITIAL,
28*12fd6cc2SKarsten Heimrich 	UNDECIDED,
29*12fd6cc2SKarsten Heimrich 	UNMATCHED,
30*12fd6cc2SKarsten Heimrich 	MATCHED
31*12fd6cc2SKarsten Heimrich };
32*12fd6cc2SKarsten Heimrich 
33*12fd6cc2SKarsten Heimrich #define WRITE_TO_RUN_BUF(byte) { if (write) *runbuf ++ = byte; else runbuf ++; }
34*12fd6cc2SKarsten Heimrich #define WRITE_CONTROL(byte) { if (write) *control = byte; }
35*12fd6cc2SKarsten Heimrich 
36*12fd6cc2SKarsten Heimrich template <bool write>
37*12fd6cc2SKarsten Heimrich class PackBits {
38*12fd6cc2SKarsten Heimrich public:
39*12fd6cc2SKarsten Heimrich 	static int doIt(unsigned char *pOut, const unsigned char *pIn, int n)
40*12fd6cc2SKarsten Heimrich 	{
41*12fd6cc2SKarsten Heimrich 		int i;
42*12fd6cc2SKarsten Heimrich 		unsigned char *control;
43*12fd6cc2SKarsten Heimrich 		unsigned char *runbuf;
44*12fd6cc2SKarsten Heimrich 		unsigned char thisbyte;
45*12fd6cc2SKarsten Heimrich 		unsigned char runbyte;
46*12fd6cc2SKarsten Heimrich 		STATUS status;
47*12fd6cc2SKarsten Heimrich 
48*12fd6cc2SKarsten Heimrich 		i = 0;
49*12fd6cc2SKarsten Heimrich 		status  = INITIAL;
50*12fd6cc2SKarsten Heimrich 		control = runbuf = pOut;
51*12fd6cc2SKarsten Heimrich 		runbyte = *pIn++;
52*12fd6cc2SKarsten Heimrich 
53*12fd6cc2SKarsten Heimrich 		while (--n) {
54*12fd6cc2SKarsten Heimrich 			thisbyte = *pIn++;
55*12fd6cc2SKarsten Heimrich 			switch (status) {
56*12fd6cc2SKarsten Heimrich 			case INITIAL:
57*12fd6cc2SKarsten Heimrich 				control   = runbuf++;
58*12fd6cc2SKarsten Heimrich 				WRITE_TO_RUN_BUF(runbyte);
59*12fd6cc2SKarsten Heimrich 				if (thisbyte == runbyte) {
60*12fd6cc2SKarsten Heimrich 					status = UNDECIDED;
61*12fd6cc2SKarsten Heimrich 				} else {
62*12fd6cc2SKarsten Heimrich 					runbyte = thisbyte;
63*12fd6cc2SKarsten Heimrich 					status  = UNMATCHED;
64*12fd6cc2SKarsten Heimrich 				}
65*12fd6cc2SKarsten Heimrich 				i = 1;
66*12fd6cc2SKarsten Heimrich 				break;
67*12fd6cc2SKarsten Heimrich 
68*12fd6cc2SKarsten Heimrich 			case UNDECIDED:
69*12fd6cc2SKarsten Heimrich 				if (i == MAXINBYTES) {
70*12fd6cc2SKarsten Heimrich 					WRITE_CONTROL(CONTROL2(i));
71*12fd6cc2SKarsten Heimrich 					WRITE_TO_RUN_BUF(runbyte);
72*12fd6cc2SKarsten Heimrich 					runbyte   = thisbyte;
73*12fd6cc2SKarsten Heimrich 					status    = INITIAL;
74*12fd6cc2SKarsten Heimrich 				} else if (thisbyte == runbyte) {
75*12fd6cc2SKarsten Heimrich 					if (i > 1) {
76*12fd6cc2SKarsten Heimrich 						WRITE_CONTROL(CONTROL2(i - 2));
77*12fd6cc2SKarsten Heimrich 						control  = runbuf - 1;
78*12fd6cc2SKarsten Heimrich 					}
79*12fd6cc2SKarsten Heimrich 					i = 2;
80*12fd6cc2SKarsten Heimrich 					status = MATCHED;
81*12fd6cc2SKarsten Heimrich 				} else {
82*12fd6cc2SKarsten Heimrich 					WRITE_TO_RUN_BUF(runbyte);
83*12fd6cc2SKarsten Heimrich 					runbyte   = thisbyte;
84*12fd6cc2SKarsten Heimrich 					status    = UNMATCHED;
85*12fd6cc2SKarsten Heimrich 					i++;
86*12fd6cc2SKarsten Heimrich 				}
87*12fd6cc2SKarsten Heimrich 				break;
88*12fd6cc2SKarsten Heimrich 
89*12fd6cc2SKarsten Heimrich 			case UNMATCHED:
90*12fd6cc2SKarsten Heimrich 				if (i == MAXINBYTES) {
91*12fd6cc2SKarsten Heimrich 					WRITE_CONTROL(CONTROL2(i));
92*12fd6cc2SKarsten Heimrich 					status   = INITIAL;
93*12fd6cc2SKarsten Heimrich 				} else {
94*12fd6cc2SKarsten Heimrich 					if (thisbyte == runbyte) {
95*12fd6cc2SKarsten Heimrich 						status = UNDECIDED;
96*12fd6cc2SKarsten Heimrich 					}
97*12fd6cc2SKarsten Heimrich 					i++;
98*12fd6cc2SKarsten Heimrich 				}
99*12fd6cc2SKarsten Heimrich 				WRITE_TO_RUN_BUF(runbyte);
100*12fd6cc2SKarsten Heimrich 				runbyte   = thisbyte;
101*12fd6cc2SKarsten Heimrich 				break;
102*12fd6cc2SKarsten Heimrich 
103*12fd6cc2SKarsten Heimrich 			case MATCHED:
104*12fd6cc2SKarsten Heimrich 				if ((thisbyte != runbyte) || (i == MAXINBYTES)) {
105*12fd6cc2SKarsten Heimrich 					runbuf    = control;
106*12fd6cc2SKarsten Heimrich 					WRITE_TO_RUN_BUF(CONTROL1(i));
107*12fd6cc2SKarsten Heimrich 					WRITE_TO_RUN_BUF(runbyte);
108*12fd6cc2SKarsten Heimrich 					runbyte   = thisbyte;
109*12fd6cc2SKarsten Heimrich 					status    = INITIAL;
110*12fd6cc2SKarsten Heimrich 				} else {
111*12fd6cc2SKarsten Heimrich 					i++;
112*12fd6cc2SKarsten Heimrich 				}
113*12fd6cc2SKarsten Heimrich 				break;
114*12fd6cc2SKarsten Heimrich 			}
115*12fd6cc2SKarsten Heimrich 		}
116*12fd6cc2SKarsten Heimrich 
117*12fd6cc2SKarsten Heimrich 		switch (status) {
118*12fd6cc2SKarsten Heimrich 		case INITIAL:
119*12fd6cc2SKarsten Heimrich 			WRITE_TO_RUN_BUF(CONTROL2(1));
120*12fd6cc2SKarsten Heimrich 			break;
121*12fd6cc2SKarsten Heimrich 		case UNDECIDED:
122*12fd6cc2SKarsten Heimrich 		case UNMATCHED:
123*12fd6cc2SKarsten Heimrich 			WRITE_CONTROL(CONTROL2(i));
124*12fd6cc2SKarsten Heimrich 			break;
125*12fd6cc2SKarsten Heimrich 		case MATCHED:
126*12fd6cc2SKarsten Heimrich 			runbuf    = control;
127*12fd6cc2SKarsten Heimrich 			WRITE_TO_RUN_BUF(CONTROL1(i));
128*12fd6cc2SKarsten Heimrich 			break;
129*12fd6cc2SKarsten Heimrich 		}
130*12fd6cc2SKarsten Heimrich 		WRITE_TO_RUN_BUF(runbyte);
131*12fd6cc2SKarsten Heimrich 
132*12fd6cc2SKarsten Heimrich 		return runbuf - pOut;
133*12fd6cc2SKarsten Heimrich 	}
134*12fd6cc2SKarsten Heimrich };
135*12fd6cc2SKarsten Heimrich 
136*12fd6cc2SKarsten Heimrich 
137*12fd6cc2SKarsten Heimrich int pack_bits_size(const unsigned char *pIn, int n)
138*12fd6cc2SKarsten Heimrich {
139*12fd6cc2SKarsten Heimrich 	PackBits<false> calculateSize;
140*12fd6cc2SKarsten Heimrich 	return calculateSize.doIt(NULL, pIn, n);
141*12fd6cc2SKarsten Heimrich }
142*12fd6cc2SKarsten Heimrich 
143*12fd6cc2SKarsten Heimrich int pack_bits(unsigned char *pOut, const unsigned char *pIn, int n)
144*12fd6cc2SKarsten Heimrich {
145*12fd6cc2SKarsten Heimrich 	PackBits<true> compress;
146*12fd6cc2SKarsten Heimrich 	return compress.doIt(pOut, pIn, n);
147*12fd6cc2SKarsten Heimrich }
148*12fd6cc2SKarsten Heimrich 
149*12fd6cc2SKarsten Heimrich #ifdef DBG_CON_STREAM
150*12fd6cc2SKarsten Heimrich int main(int argc, char **argv)
151*12fd6cc2SKarsten Heimrich {
152*12fd6cc2SKarsten Heimrich 	if (argc < 2) {
153*12fd6cc2SKarsten Heimrich 		return -1;
154*12fd6cc2SKarsten Heimrich 	}
155*12fd6cc2SKarsten Heimrich 
156*12fd6cc2SKarsten Heimrich 	FILE *input = fopen(*++argv, "rb");
157*12fd6cc2SKarsten Heimrich 	if (input == NULL) {
158*12fd6cc2SKarsten Heimrich 		return -1;
159*12fd6cc2SKarsten Heimrich 	}
160*12fd6cc2SKarsten Heimrich 
161*12fd6cc2SKarsten Heimrich 	FILE *output = fopen("rle.out", "wb");
162*12fd6cc2SKarsten Heimrich 	if (output == NULL) {
163*12fd6cc2SKarsten Heimrich 		fclose(input);
164*12fd6cc2SKarsten Heimrich 		return -1;
165*12fd6cc2SKarsten Heimrich 	}
166*12fd6cc2SKarsten Heimrich 
167*12fd6cc2SKarsten Heimrich 	fseek(input, 0, SEEK_END);
168*12fd6cc2SKarsten Heimrich 	long size = ftell(input);
169*12fd6cc2SKarsten Heimrich 	fseek(input, 0, SEEK_SET);
170*12fd6cc2SKarsten Heimrich 
171*12fd6cc2SKarsten Heimrich 	unsigned char *pIn  = new unsigned char[size];
172*12fd6cc2SKarsten Heimrich 	fread(pIn, size, 1, input);
173*12fd6cc2SKarsten Heimrich 
174*12fd6cc2SKarsten Heimrich 	long outSize = pack_bits_size(pIn, size);
175*12fd6cc2SKarsten Heimrich 	printf("input size: %d\noutput size: %d\n", (int)size, (int)outSize);
176*12fd6cc2SKarsten Heimrich 
177*12fd6cc2SKarsten Heimrich 	unsigned char *pOut = new unsigned char[outSize];
178*12fd6cc2SKarsten Heimrich 
179*12fd6cc2SKarsten Heimrich 	int cnt = pack_bits(pOut, pIn, size);
180*12fd6cc2SKarsten Heimrich 
181*12fd6cc2SKarsten Heimrich 	fwrite(pOut, cnt, 1, output);
182*12fd6cc2SKarsten Heimrich 
183*12fd6cc2SKarsten Heimrich 	fclose(input);
184*12fd6cc2SKarsten Heimrich 	fclose(output);
185*12fd6cc2SKarsten Heimrich 
186*12fd6cc2SKarsten Heimrich 	delete [] pIn;
187*12fd6cc2SKarsten Heimrich 	delete [] pOut;
188*12fd6cc2SKarsten Heimrich 
189*12fd6cc2SKarsten Heimrich }
190*12fd6cc2SKarsten Heimrich #endif
191