void sortmarks(int *Arr, int first, int last){ int i, j, pivot, temp; if (first<last){ pivot = first; i = first; j = last; while (i<j){ while (Arr[i] <= Arr[pivot] && i<last) i++; while (Arr[j]>Arr[pivot]) j--; if (i<j){ temp = Arr[i]; Arr[i] = Arr[j]; Arr[j] = temp; } } temp = Arr[pivot]; Arr[pivot] = Arr[j]; Arr[j] = temp; sortmarks(Arr, first, j - 1); sortmarks(Arr, j + 1, last); } }
void * removeArrayDuplicates(int *Arr, int len) { int i, j; if (Arr == NULL || len < 0) return NULL; else { sortmarks(Arr, 0, len-1); for (i = 0, j = 0; i < len; i++) { if (Arr[i] != Arr[i + 1]) { Arr[j] = Arr[i]; j++; } else Arr[j] = Arr[i]; } } }
int main (int argc, char *args[]) { int i, n, r, c, ch; FILE *inf; marklistptr library = NULL, list = NULL, step = NULL; marklistptr symbol_list = NULL; marktype d, d2; Pixel **bitmap, **recon, **bitmapcopy; char *splitfilename = NULL; int cols, rows, count, librarysize, lossy = 1; int quick = 0; int ticencode = 0, ticdecode = 0, external = 0; char *libraryname = NULL, *infile = NULL; char *s1 = NULL, *s2 = NULL; char bufferin[BUFSIZ], bufferout[BUFSIZ]; if (argc < 2) usage (); while ((ch = getopt (argc, args, "edlLQhvXR:")) != -1) switch (ch) { case 'e': ticencode = 1; break; case 'd': ticdecode = 1; break; case 'l': lossy = 1; break; case 'L': lossy = 0; break; case 'Q': quick = 1; break; case 'v': V = 1; break; case 'X': external = 1; break; case 'R': splitfilename = optarg; break; case 'h': case '?': usage (); } for (i = 1; i < argc; i++) if (args[i][0] != '-') if (strcmp (args[i - 1], "-R")) { /* ignore arg following -R, ie. -R <filename> */ if (!s1) s1 = args[i]; else if (!s2) s2 = args[i]; else error_msg (args[0], "too many filenames", ""); } if (ticencode == ticdecode) error_msg (args[0], "please specify either encode XOR decode", ""); if (ticencode) { /***************** ENCODING STAGE *****************/ long PrevBits = 0; long BITS_header = 0, BITS_symbols = 0, BITS_offsets = 0, BITS_residue = 0, BITS_footer = 0, BITS_library = 0; libraryname = s1; if (!libraryname) error_msg (args[0], "please specify a library file", ""); infile = s2; if (!infile) error_msg (args[0], "please specify a file name", ""); inf = fopen (infile, "rb"); if (inf == NULL) error_msg (args[0], "Trouble opening file:", infile); setbuf (inf, bufferin); count = librarysize = read_library (libraryname, &library); if (V) fprintf (stderr, "%s: processing...\n", args[0]); if (pbm_isapbmfile (inf)) { if (V) fprintf (stderr, "reading file %s...\n", infile); bitmap = pbm_readfile (inf, &cols, &rows); fclose (inf); bitmapcopy = pbm_copy (bitmap, cols, rows); if (V) fprintf (stderr, "extracting..."); ExtractAllMarks (bitmap, &list, cols, rows); if (V) fprintf (stderr, "(%d marks)\n", marklist_length (list)); /* sort into reading order */ if (V) fprintf (stderr, "sorting...\n"); list = sortmarks (list); pbm_freearray (&bitmap, rows); /* clear old version */ bitmap = bitmapcopy; /* point to the copy */ recon = pbm_allocarray (cols, rows); if (V) fprintf (stderr, "matching..."); match_sequence (list, library, &symbol_list, recon, quick); PrevBits = 0; setbuf (stdout, bufferout); /* start output */ magic_write (stdout, MAGIC_TIC); InitArithEncoding (); EncodeGammaDist (1); /* version 1 of the program */ EncodeGammaDist (lossy); /* lossy=1 = no residue */ EncodeGammaDist (external); /* 1== external file */ count = marklist_length (symbol_list); if (V) fprintf (stderr, "encoding cols, rows, and number of symbols=%d\n", count); EncodeGammaDist (cols); EncodeGammaDist (rows); EncodeGammaDist (count); EncodeGammaDist (librarysize); BITS_header = CountOfBitsOut - PrevBits; PrevBits = CountOfBitsOut; /* output the library sequence */ if (external == 0) { if (V) fprintf (stderr, "encoding library\n"); bl_clearmodel (); bl_writetemplate (library_template); for (step = library; step; step = step->next) bl_compress_mark (step->data); bl_freemodel (); BITS_library = CountOfBitsOut - PrevBits; PrevBits = CountOfBitsOut; } /* output the symbol sequence */ if (V) fprintf (stderr, "encoding symbol sequence\n"); InitPPM (); EncodeSymbols (symbol_list, count); BITS_symbols = CountOfBitsOut - PrevBits; PrevBits = CountOfBitsOut; /* output the offset sequence */ if (V) fprintf (stderr, "encoding offset sequence\n"); EncodeOffsets (symbol_list, count); BITS_offsets = CountOfBitsOut - PrevBits; PrevBits = CountOfBitsOut; EncodeChecksum (); /* code lossy checksum */ /* calculate the residue...and compress it---if need be! */ if (!lossy) { if (V) fprintf (stderr, "encoding residue...\n"); d.bitmap = bitmap; d.h = rows; d.w = cols; d2.bitmap = recon; d2.h = rows; d2.w = cols; if (splitfilename) { FILE *temp; CloseDownArithEncoding (); fclose (stdout); /* no residue result */ BITS_footer = CountOfBitsOut - PrevBits; temp = fopen (splitfilename, "wb"); if (temp == NULL) error_msg (args[0], "Trouble creating file:", splitfilename); arith_out = temp; InitArithEncoding (); bl_clair_compress (d, d2); CloseDownArithEncoding (); BITS_residue = CountOfBitsOut; fclose (temp); } else { bl_clair_compress (d, d2); BITS_residue = CountOfBitsOut - PrevBits; PrevBits = CountOfBitsOut; EncodeChecksum (); /* code lossless checksum */ CloseDownArithEncoding (); BITS_footer = CountOfBitsOut - PrevBits; } } else { if (V) fprintf (stderr, "not encoding residue..lossy mode\n"); CloseDownArithEncoding (); BITS_footer = CountOfBitsOut - PrevBits; } /* because we edit the values above */ CountOfBitsOut = BITS_header + BITS_library + BITS_symbols + BITS_offsets + BITS_residue + BITS_footer; fprintf (stderr, "bits: header=%ld, library=%ld, " "symbols=%ld, offsets=%ld, residue=%ld, footer=%ld\n", BITS_header, BITS_library, BITS_symbols, BITS_offsets, BITS_residue, BITS_footer); fprintf (stderr, "total bits: %ld, ", CountOfBitsOut); fprintf (stderr, "Lossy CR: %4.2f", (cols * rows) / (float) (CountOfBitsOut - BITS_residue)); if (external) fprintf (stderr, " (excluding external lib)"); fprintf (stderr, ", Lossless CR: %4.2f\n", (!lossy) * (cols * rows) / (float) (CountOfBitsOut)); } else error_msg (args[0], "unknown format of bitmap--expecting PBM.", ""); } else { /***************** DECODING STAGE *****************/ int lastx, lasty; librarysize = 0; if (external) { libraryname = s1; infile = s2; count = librarysize = read_library (libraryname, &library); } else { infile = s1; if (infile && s2) error_msg (args[0], "too many filenames", ""); } if (!freopen (infile, "rb", stdin)) error_msg (args[0], "Trouble opening file:", infile); if (V) fprintf (stderr, "decompressing...\n"); setbuf (stdin, bufferin); magic_check (stdin, MAGIC_TIC); InitArithDecoding (); { int version = DecodeGammaDist (); if (version != 1) error_msg (args[0], "Need later version of decompressor.", ""); } { int templossy = DecodeGammaDist (); if (!lossy) lossy = templossy; /* can only choose if encoded file is lossless */ if (V) { if (lossy) fprintf (stderr, "lossy mode\n"); else fprintf (stderr, "lossless mode\n"); } } if (DecodeGammaDist ()) { /* if compressed file doesn't contain library */ if (!external) error_msg (args[0], "compressed file doesn't contain library, specify externally", ""); external = 1; } else { /* if compressed file contains library */ if (external) fprintf (stderr, "ignoring external library file\n"); external = 0; } cols = DecodeGammaDist (); rows = DecodeGammaDist (); count = DecodeGammaDist (); i = DecodeGammaDist (); /* librarysize */ if (external) { if (i > librarysize) error_msg (args[0], "external library file is too small!", ""); else if (i < librarysize) fprintf (stderr, "%s: warning, expecting a different (smaller) library.\n", args[0]); } librarysize = i; if (V) fprintf (stderr, "cols %d, rows %d, num syms %d, library size %d\n", cols, rows, count, librarysize); /* decode library */ if (external == 0) { if (V) fprintf (stderr, "reading library\n"); bl_clearmodel (); bl_readtemplate (); for (n = 0; n < librarysize; n++) { bl_decompress_mark (&d); d.symnum = n; if (library == NULL) step = marklist_add (&library, d); else step = marklist_add (&step, d); } bl_freemodel (); if (V) fprintf (stderr, "read %d marks from library\n", marklist_length (library)); } recon = pbm_allocarray (cols, rows); /* decode symbols */ InitPPM (); if (V) fprintf (stderr, "decompressing %d symbols\n", count); symbol_list = DecodeSymbols (count); /* decode offsets */ if (V) fprintf (stderr, "reading offsets...\n"); DecodeOffsets (symbol_list, count); lastx = lasty = 0; for (step = symbol_list; step; step = step->next) { lastx = lastx + step->data.xoffset; lasty = lasty + step->data.yoffset; marklist_getat (library, step->data.symnum, &d2); for (r = 0; r < d2.h; r++) for (c = 0; c < d2.w; c++) if (pbm_getpixel (d2.bitmap, c, r)) pbm_putpixel_trunc (recon, lastx + c, lasty + r, 1, cols, rows); /* we don't care, already warned them! */ lastx += d2.w; } DecodeChecksum (args[0]); /* decode the residue */ if (!lossy) { if (V) fprintf (stderr, "decoding residue...\n"); bitmap = pbm_allocarray (cols, rows); d.bitmap = bitmap; d.w = d2.w = cols; d.h = d2.h = rows; d2.bitmap = recon; /* NOTE: the 2nd argument is clairvoyantly compressed */ if (splitfilename) { FILE *temp; CloseDownArithDecoding (); fclose (stdin); temp = fopen (splitfilename, "rb"); if (temp == NULL) error_msg (args[0], "Trouble opening file:", splitfilename); arith_in = temp; InitArithDecoding (); bl_clair_decompress (d, d2); CloseDownArithDecoding (); fclose (temp); } else { bl_clair_decompress (d, d2); DecodeChecksum (args[0]); CloseDownArithDecoding (); } pbm_freearray (&recon, rows); recon = bitmap; /* point to the bitmap */ } else { CloseDownArithDecoding (); } if (V) fprintf (stderr, "writing pbm file...\n"); setbuf (stdout, bufferout); pbm_writefile (stdout, recon, cols, rows); pbm_freearray (&recon, rows); } /* end decoding */ exit(0); }