Ejemplo n.º 1
0
/****************************************************************************
*   Function   : EncodeLZSSByFile
*   Description: This function will read an input file and write an output
*                file encoded according to the traditional LZSS algorithm.
*                This algorithm encodes strings as 16 bits (a 12 bit offset
*                + a 4 bit length).
*   Parameters : fpIn - pointer to the open binary file to encode
*                fpOut - pointer to the open binary file to write encoded
*                       output
*   Effects    : fpIn is encoded and written to fpOut.  Neither file is
*                closed after exit.
*   Returned   : EXIT_SUCCESS or EXIT_FAILURE
****************************************************************************/
int EncodeLZSSByFile(FILE *fpIn, FILE *fpOut)
{
    bit_file_t *bfpOut;

    encoded_string_t matchData;
    unsigned int i, c;
    unsigned int len;                       /* length of string */

    /* head of sliding window and lookahead */
    unsigned int windowHead, uncodedHead;

    /* use stdin if no input file */
    if (fpIn == NULL)
    {
        fpIn = stdin;
    }

    if (fpOut == NULL)
    {
        /* use stdout if no output file */
        bfpOut = MakeBitFile(stdout, BF_WRITE);
    }
    else
    {
        /* convert output file to bitfile */
        bfpOut = MakeBitFile(fpOut, BF_WRITE);
    }

    windowHead = 0;
    uncodedHead = 0;

    /* Window Size : 2^12 same as offset  */
    /************************************************************************
    * Fill the sliding window buffer with some known vales.  DecodeLZSS must
    * use the same values.  If common characters are used, there's an
    * increased chance of matching to the earlier strings.
    ************************************************************************/
    memset(slidingWindow, ' ', WINDOW_SIZE * sizeof(unsigned char));

    /* MAX_CODED : 2 to 17 because we cant have 0 to 1 */
    /************************************************************************
    * Copy MAX_CODED bytes from the input file into the uncoded lookahead
    * buffer.
    ************************************************************************/
    for (len = 0; len < MAX_CODED && (c = getc(fpIn)) != EOF; len++)
    {
        uncodedLookahead[len] = c;
    }

    if (len == 0)
    {
        return (EXIT_SUCCESS);   /* inFile was empty */
    }

    /* Look for matching string in sliding window */
    InitializeSearchStructures();
    matchData = FindMatch(windowHead, uncodedHead);

    /* now encoded the rest of the file until an EOF is read */
    while (len > 0)
    {
        if (matchData.length > len)
        {
            /* garbage beyond last data happened to extend match length */
            matchData.length = len;
        }

        if (matchData.length <= MAX_UNCODED)
        {
            /* not long enough match.  write uncoded flag and character */
            BitFilePutBit(UNCODED, bfpOut);
            BitFilePutChar(uncodedLookahead[uncodedHead], bfpOut);

            matchData.length = 1;   /* set to 1 for 1 byte uncoded */
        }
        else
        {
            unsigned int adjustedLen;

            /* adjust the length of the match so minimun encoded len is 0*/
            adjustedLen = matchData.length - (MAX_UNCODED + 1);

            /* match length > MAX_UNCODED.  Encode as offset and length. */
            BitFilePutBit(ENCODED, bfpOut);
            BitFilePutBitsInt(bfpOut, &matchData.offset, OFFSET_BITS,
                sizeof(unsigned int));
            BitFilePutBitsInt(bfpOut, &adjustedLen, LENGTH_BITS,
                sizeof(unsigned int));
        }

        /********************************************************************
        * Replace the matchData.length worth of bytes we've matched in the
        * sliding window with new bytes from the input file.
        ********************************************************************/
        i = 0;
        while ((i < matchData.length) && ((c = getc(fpIn)) != EOF))
        {
            /* add old byte into sliding window and new into lookahead */
            ReplaceChar(windowHead, uncodedLookahead[uncodedHead]);
            uncodedLookahead[uncodedHead] = c;
            windowHead = Wrap((windowHead + 1), WINDOW_SIZE);
            uncodedHead = Wrap((uncodedHead + 1), MAX_CODED);
            i++;
        }

        /* handle case where we hit EOF before filling lookahead */
        while (i < matchData.length)
        {
            ReplaceChar(windowHead, uncodedLookahead[uncodedHead]);
            /* nothing to add to lookahead here */
            windowHead = Wrap((windowHead + 1), WINDOW_SIZE);
            uncodedHead = Wrap((uncodedHead + 1), MAX_CODED);
            len--;
            i++;
        }

        /* find match for the remaining characters */
        matchData = FindMatch(windowHead, uncodedHead);
    }

    /* we've decoded everything, free bitfile structure */
    BitFileToFILE(bfpOut);

   return (EXIT_SUCCESS);
}
Ejemplo n.º 2
0
/**
  * Loads a DWT file
  */
void DWT::load(const string &fileName)
{
	// Open file and read magic number
	FILE *fHan = fopen(fileName.data(), "rb");
	char thisMagic[2];
	fread(thisMagic, 1, 2, fHan);
	if (magic[0] != thisMagic[0] || magic[1] != thisMagic[1]) {
		cerr << "Unrecognized file format for " << fileName << endl;
		exit(1);
	}

	// Read header
	fread(&bpp, sizeof(bpp), 1, fHan);
	fread(&realWidth, sizeof(int), 1, fHan);
	fread(&realHeight, sizeof(int), 1, fHan);
#ifdef __BIG_ENDIAN__
	bpp = swap_endian32(bpp);
	realWidth = swap_endian32(realWidth);
	realHeight = swap_endian32(realHeight);
#endif

	// Calculate padded width and height
	width = 1;
	while (width < realWidth) width <<= 1;
	height = 1;
	while (height < realHeight) height <<= 1;

	// Drops half of the padding when reading
	unsigned int stopHeight = height - (height - realHeight)/2;
	unsigned int stopWidth = width - (width - realWidth)/2;
	unsigned int stopPrHeight = stopHeight * PREVIEW / height;
	unsigned int stopPrWidth = stopWidth * PREVIEW / width;

	cout	<< "bpp: " << bpp << endl
			<< "width: " << width << endl
			<< "height: " << height << endl
			<< "realWidth: " << realWidth << endl
			<< "realHeight: " << realHeight << endl;

	coeff = new float[width * height];
	int maxAbsVal;
	fread(&maxAbsVal, sizeof(int), 1, fHan);
	cout << "maxValue: " << maxAbsVal << endl;

	const float C = ((1 << (bpp-1))-1)/(float)(maxAbsVal);	// Range value
	const float M = (1 << (bpp-1));							// Added to get only positive values
	float W = 1, w = 1/sqrt(2);							// Factor of multiplication for preview
	for (unsigned int i = PREVIEW; i < height; i <<= 1) W *= w;
	for (unsigned int i = PREVIEW; i < width; i <<= 1) W *= w;

	// Reading the preview
	for (unsigned int i = 0; i < stopPrHeight && i < PREVIEW; i++) {
		for (unsigned int j = 0; j < stopPrWidth && j < PREVIEW; j++) {
			unsigned char l;
			fread(&l, 1, 1, fHan);
			coeff[i*width + j] = l/W;
		}
	}

	// Reading the rest of the transform, decoding Huffman and RLE
	unsigned int zeros = 0;
	bit_file_t *bf = MakeBitFile(fHan, BF_READ);
	Huffman *huffman = new Huffman(bpp);
	huffman->setFile(bf);
	huffman->readTree();
	for (unsigned int i = 0; i < stopHeight; i++) {
		for (unsigned int j = 0; j < stopWidth; j++) {
			if (i >= PREVIEW || j >= PREVIEW) {
				int l = 0;
				if (zeros > 0) {
					coeff[i * width + j] = 0;
					zeros--;
				} else {
					bool seq0 = BitFileGetBit(bf);
					if (seq0) {
						// RLE: read the number of coefficents to set to 0 and set the first
						coeff[i * width + j] = 0;
						bool cod8 = BitFileGetBit(bf);
						if (cod8) {
							BitFileGetBitsInt(bf, &zeros, 8, sizeof(zeros));
						} else {
							BitFileGetBitsInt(bf, &zeros, 3, sizeof(zeros));
						}
					} else {
						// Huffman: read coefficent and dequantize it
						l = huffman->readSymbol();
						coeff[i*width + j] = (l-M)/C;
					}
				}
			}
		}
	}
	delete huffman;

	fclose(fHan);
}
Ejemplo n.º 3
0
/****************************************************************************
*   Function   : HuffmanEncodeFile
*   Description: This routine genrates a huffman tree optimized for a file
*                and writes out an encoded version of that file.
*   Parameters : inFile - Open file pointer for file to encode (must be
*                         rewindable).
*                outFile - Open file pointer for file receiving encoded data
*   Effects    : File is Huffman encoded
*   Returned   : 0 for success, -1 for failure.  errno will be set in the
*                event of a failure.  Either way, inFile and outFile will
*                be left open.
****************************************************************************/
int HuffmanEncodeFile(FILE *inFile, FILE *outFile)
{
    huffman_node_t *huffmanTree;        /* root of huffman tree */
    code_list_t codeList[NUM_CHARS];    /* table for quick encode */
    bit_file_t *bOutFile;
    int c;

    /* validate input and output files */
    if ((NULL == inFile) || (NULL == outFile))
    {
        errno = ENOENT;
        return -1;
    }

    bOutFile = MakeBitFile(outFile, BF_WRITE);

    if (NULL == bOutFile)
    {
        perror("Making Output File a BitFile");
        return -1;
    }

    /* build tree */
    if ((huffmanTree = GenerateTreeFromFile(inFile)) == NULL)
    {
        outFile = BitFileToFILE(bOutFile);
        return -1;
    }

    /* build a list of codes for each symbol */

    /* initialize code list */
    for (c = 0; c < NUM_CHARS; c++)
    {
        codeList[c].code = NULL;
        codeList[c].codeLen = 0;
    }

    if (0 != MakeCodeList(huffmanTree, codeList))
    {
        outFile = BitFileToFILE(bOutFile);
        return -1;
    }

    /* write out encoded file */

    /* write header for rebuilding of tree */
    WriteHeader(huffmanTree, bOutFile);

    /* read characters from file and write them to encoded file */
    rewind(inFile);         /* start another pass on the input file */

    while((c = fgetc(inFile)) != EOF)
    {
        BitFilePutBits(bOutFile,
                       BitArrayGetBits(codeList[c].code),
                       codeList[c].codeLen);
    }

    /* now write EOF */
    BitFilePutBits(bOutFile,
                   BitArrayGetBits(codeList[EOF_CHAR].code),
                   codeList[EOF_CHAR].codeLen);

    /* free the code list */
    for (c = 0; c < NUM_CHARS; c++)
    {
        if (codeList[c].code != NULL)
        {
            BitArrayDestroy(codeList[c].code);
        }
    }

    /* clean up */
    outFile = BitFileToFILE(bOutFile);          /* make file normal again */
    FreeHuffmanTree(huffmanTree);               /* free allocated memory */

    return 0;
}
Ejemplo n.º 4
0
/**
  * Saves a DWT file
  */
void DWT::save(const string &fileName)
{
	FILE *fHan = fopen(fileName.data(), "wb");

	// Header
	fwrite(&magic, 1, 2, fHan);
#ifdef __BIG_ENDIAN__
	// Correct endianness for writing
	bpp = swap_endian32(bpp);
	realWidth = swap_endian32(realWidth);
	realHeight = swap_endian32(realHeight);
#endif
	fwrite(&bpp, sizeof(bpp), 1, fHan);
	fwrite(&realWidth, sizeof(int), 1, fHan);
	fwrite(&realHeight, sizeof(int), 1, fHan);
#ifdef __BIG_ENDIAN__
	// Revert endianness
	bpp = swap_endian32(bpp);
	realWidth = swap_endian32(realWidth);
	realHeight = swap_endian32(realHeight);
#endif

	// Drops half of the padding when writing
	unsigned int stopHeight = height - (height - realHeight)/2;
	unsigned int stopWidth = width - (width - realWidth)/2;
	unsigned int stopPrHeight = stopHeight * PREVIEW / height;
	unsigned int stopPrWidth = stopWidth * PREVIEW / width;

	// Looking for the highest absolute value in the transformation, used for quantization
	float maxAbsValF = 0;
	for (unsigned int i = 0; i < stopHeight; i++) {
		for (unsigned int j = 0; j < stopWidth; j++){
			if (i >= PREVIEW || j >= PREVIEW) {
				if (abs(coeff[i*width+j]) > maxAbsValF) maxAbsValF = abs(coeff[i*width+j]);
			}
		}
	}
	int maxAbsVal = round(maxAbsValF);
	cout << "maxValue: " << maxAbsVal << endl;
	fwrite(&maxAbsVal, sizeof(int), 1, fHan);

	const float C = ((1 << (bpp-1))-1)/(float)(maxAbsVal);	// Range value
	const float M = (1 << (bpp-1));							// Added to get only positive values
	float W = 1, w = 1/sqrt(2);							// Factor of multiplication for preview
	for (unsigned int i = PREVIEW; i < height; i <<= 1) W *= w;
	for (unsigned int i = PREVIEW; i < width; i <<= 1) W *= w;

	// Huffman, searching for occurrences in the quantization
	unsigned int *occ = new unsigned int[1 << bpp];
	memset(occ, 0, (1 << bpp)*sizeof(int));
	for (unsigned int i = 0; i < stopHeight; i++) {
		for (unsigned int j = 0; j < stopWidth; j++){
			if (i >= PREVIEW || j >= PREVIEW) {
				float quant = coeff[i * width + j] * C;
				if (abs(quant) >= .5f)
					occ[range(round(quant + M))]++;
			}
		}
	}
	Huffman *huffman = new Huffman(bpp);
	huffman->buildTree(occ, 1<<bpp);
	delete[] occ;

	// Encoding of the preview
	for (unsigned int i = 0; i < stopPrHeight && i < PREVIEW; i++) {
		for (unsigned int j = 0; j < stopPrWidth && j < PREVIEW; j++) {
			unsigned char l = coeff[i*width + j] * W;
			fwrite(&l, 1, 1, fHan);
		}
	}

	// Encoding of the rest of the transform, using Huffman and RLE
	int zeros = 0;
	bit_file_t *bf = MakeBitFile(fHan, BF_APPEND);
	huffman->setFile(bf);
	huffman->writeTree();
	for (unsigned int i = 0; i < stopHeight; i++) {
		for (unsigned int j = 0; j < stopWidth; j++) {
			if (i >= PREVIEW || j >= PREVIEW) {
				bool zero = abs(coeff[i*width + j]*C) < .5f;
				if (zero) zeros++;
				if (!zero || (i==stopHeight-1 && j==stopWidth-1)) {
					if (zeros != 0) {
						// RLE: a sequence of zeros has been found
						if (zeros <= 8) {
							unsigned int n = zeros-1;
							BitFilePutBit(1, bf);
							BitFilePutBit(0, bf);
							BitFilePutBitsInt(bf, &n, 3, sizeof(n));
						} else {
							while (zeros > 0) {
								unsigned int n = zeros > 256 ? 255 : zeros-1;
								BitFilePutBit(1, bf);
								BitFilePutBit(1, bf);
								BitFilePutBitsInt(bf, &n, 8, sizeof(n));
								zeros -= 256;
							}
						}
						zeros = 0;
					}
					if (i!=stopHeight-1 || j!=stopWidth-1) {
						// Huffman: write a quantized and then Huffman-encoded value
						unsigned int l = range(round(coeff[i*width + j]*C + M));
						BitFilePutBit(0, bf);
						huffman->writeSymbol(l);
					}
				}
			}
		}
	}
	BitFileFlushOutput(bf, 0);
	delete huffman;

	fclose(fHan);
}
Ejemplo n.º 5
0
/****************************************************************************
*   Function   : HuffmanDecodeFile
*   Description: This routine reads a Huffman coded file and writes out a
*                decoded version of that file.
*   Parameters : inFile - Open file pointer for file to decode
*                outFile - Open file pointer for file receiving decoded data
*   Effects    : Huffman encoded file is decoded
*   Returned   : 0 for success, -1 for failure.  errno will be set in the
*                event of a failure.  Either way, inFile and outFile will
*                be left open.
****************************************************************************/
int HuffmanDecodeFile(FILE *inFile, FILE *outFile)
{
    huffman_node_t *huffmanArray[NUM_CHARS];    /* array of all leaves */
    huffman_node_t *huffmanTree;
    huffman_node_t *currentNode;
    int i, c;
    bit_file_t *bInFile;

    /* validate input and output files */
    if ((NULL == inFile) || (NULL == outFile))
    {
        errno = ENOENT;
        return -1;
    }

    bInFile = MakeBitFile(inFile, BF_READ);

    if (NULL == bInFile)
    {
        perror("Making Input File a BitFile");
        return -1;
    }

    /* allocate array of leaves for all possible characters */
    for (i = 0; i < NUM_CHARS; i++)
    {
        if ((huffmanArray[i] = AllocHuffmanNode(i)) == NULL)
        {
            /* allocation failed clear existing allocations */
            for (i--; i >= 0; i--)
            {
                free(huffmanArray[i]);
            }

            inFile = BitFileToFILE(bInFile);
            return -1;
        }
    }

    /* populate leaves with frequency information from file header */
    if (0 != ReadHeader(huffmanArray, bInFile))
    {
        for (i = 0; i < NUM_CHARS; i++)
        {
            free(huffmanArray[i]);
        }

        inFile = BitFileToFILE(bInFile);
        return -1;
    }

    /* put array of leaves into a huffman tree */
    if ((huffmanTree = BuildHuffmanTree(huffmanArray, NUM_CHARS)) == NULL)
    {
        FreeHuffmanTree(huffmanTree);
        inFile = BitFileToFILE(bInFile);
        return -1;
    }

    /* now we should have a tree that matches the tree used on the encode */
    currentNode = huffmanTree;

    while ((c = BitFileGetBit(bInFile)) != EOF)
    {
        /* traverse the tree finding matches for our characters */
        if (c != 0)
        {
            currentNode = currentNode->right;
        }
        else
        {
            currentNode = currentNode->left;
        }

        if (currentNode->value != COMPOSITE_NODE)
        {
            /* we've found a character */
            if (currentNode->value == EOF_CHAR)
            {
                /* we've just read the EOF */
                break;
            }

            fputc(currentNode->value, outFile); /* write out character */
            currentNode = huffmanTree;          /* back to top of tree */
        }
    }

    /* clean up */
    inFile = BitFileToFILE(bInFile);            /* make file normal again */
    FreeHuffmanTree(huffmanTree);     /* free allocated memory */

    return 0;
}