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